Skip to content

Instantly share code, notes, and snippets.

@N64N64
Created August 17, 2017 07:22
Show Gist options
  • Save N64N64/f26d7d73ecb62935ab72e3765bece7a7 to your computer and use it in GitHub Desktop.
Save N64N64/f26d7d73ecb62935ab72e3765bece7a7 to your computer and use it in GitHub Desktop.
This file has been truncated, but you can view the full file.
var fengari_web_cli_lua =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 66);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js
// original notice:
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
function compare(a, b) {
if (a === b) {
return 0;
}
var x = a.length;
var y = b.length;
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
if (a[i] !== b[i]) {
x = a[i];
y = b[i];
break;
}
}
if (x < y) {
return -1;
}
if (y < x) {
return 1;
}
return 0;
}
function isBuffer(b) {
if (global.Buffer && typeof global.Buffer.isBuffer === 'function') {
return global.Buffer.isBuffer(b);
}
return !!(b != null && b._isBuffer);
}
// based on node assert, original notice:
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
//
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
//
// Originally from narwhal.js (http://narwhaljs.org)
// Copyright (c) 2009 Thomas Robinson <280north.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the 'Software'), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
var util = __webpack_require__(39);
var hasOwn = Object.prototype.hasOwnProperty;
var pSlice = Array.prototype.slice;
var functionsHaveNames = (function () {
return function foo() {}.name === 'foo';
}());
function pToString (obj) {
return Object.prototype.toString.call(obj);
}
function isView(arrbuf) {
if (isBuffer(arrbuf)) {
return false;
}
if (typeof global.ArrayBuffer !== 'function') {
return false;
}
if (typeof ArrayBuffer.isView === 'function') {
return ArrayBuffer.isView(arrbuf);
}
if (!arrbuf) {
return false;
}
if (arrbuf instanceof DataView) {
return true;
}
if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
return true;
}
return false;
}
// 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.
var assert = module.exports = ok;
// 2. The AssertionError is defined in assert.
// new assert.AssertionError({ message: message,
// actual: actual,
// expected: expected })
var regex = /\s*function\s+([^\(\s]*)\s*/;
// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
function getName(func) {
if (!util.isFunction(func)) {
return;
}
if (functionsHaveNames) {
return func.name;
}
var str = func.toString();
var match = str.match(regex);
return match && match[1];
}
assert.AssertionError = function AssertionError(options) {
this.name = 'AssertionError';
this.actual = options.actual;
this.expected = options.expected;
this.operator = options.operator;
if (options.message) {
this.message = options.message;
this.generatedMessage = false;
} else {
this.message = getMessage(this);
this.generatedMessage = true;
}
var stackStartFunction = options.stackStartFunction || fail;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, stackStartFunction);
} else {
// non v8 browsers so we can have a stacktrace
var err = new Error();
if (err.stack) {
var out = err.stack;
// try to strip useless frames
var fn_name = getName(stackStartFunction);
var idx = out.indexOf('\n' + fn_name);
if (idx >= 0) {
// once we have located the function frame
// we need to strip out everything before it (and its line)
var next_line = out.indexOf('\n', idx + 1);
out = out.substring(next_line + 1);
}
this.stack = out;
}
}
};
// assert.AssertionError instanceof Error
util.inherits(assert.AssertionError, Error);
function truncate(s, n) {
if (typeof s === 'string') {
return s.length < n ? s : s.slice(0, n);
} else {
return s;
}
}
function inspect(something) {
if (functionsHaveNames || !util.isFunction(something)) {
return util.inspect(something);
}
var rawname = getName(something);
var name = rawname ? ': ' + rawname : '';
return '[Function' + name + ']';
}
function getMessage(self) {
return truncate(inspect(self.actual), 128) + ' ' +
self.operator + ' ' +
truncate(inspect(self.expected), 128);
}
// At present only the three keys mentioned above are used and
// understood by the spec. Implementations or sub modules can pass
// other keys to the AssertionError's constructor - they will be
// ignored.
// 3. All of the following functions must throw an AssertionError
// when a corresponding condition is not met, with a message that
// may be undefined if not provided. All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.
function fail(actual, expected, message, operator, stackStartFunction) {
throw new assert.AssertionError({
message: message,
actual: actual,
expected: expected,
operator: operator,
stackStartFunction: stackStartFunction
});
}
// EXTENSION! allows for well behaved errors defined elsewhere.
assert.fail = fail;
// 4. Pure assertion tests whether a value is truthy, as determined
// by !!guard.
// assert.ok(guard, message_opt);
// This statement is equivalent to assert.equal(true, !!guard,
// message_opt);. To test strictly for the value true, use
// assert.strictEqual(true, guard, message_opt);.
function ok(value, message) {
if (!value) fail(value, true, message, '==', assert.ok);
}
assert.ok = ok;
// 5. The equality assertion tests shallow, coercive equality with
// ==.
// assert.equal(actual, expected, message_opt);
assert.equal = function equal(actual, expected, message) {
if (actual != expected) fail(actual, expected, message, '==', assert.equal);
};
// 6. The non-equality assertion tests for whether two objects are not equal
// with != assert.notEqual(actual, expected, message_opt);
assert.notEqual = function notEqual(actual, expected, message) {
if (actual == expected) {
fail(actual, expected, message, '!=', assert.notEqual);
}
};
// 7. The equivalence assertion tests a deep equality relation.
// assert.deepEqual(actual, expected, message_opt);
assert.deepEqual = function deepEqual(actual, expected, message) {
if (!_deepEqual(actual, expected, false)) {
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
}
};
assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
if (!_deepEqual(actual, expected, true)) {
fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
}
};
function _deepEqual(actual, expected, strict, memos) {
// 7.1. All identical values are equivalent, as determined by ===.
if (actual === expected) {
return true;
} else if (isBuffer(actual) && isBuffer(expected)) {
return compare(actual, expected) === 0;
// 7.2. If the expected value is a Date object, the actual value is
// equivalent if it is also a Date object that refers to the same time.
} else if (util.isDate(actual) && util.isDate(expected)) {
return actual.getTime() === expected.getTime();
// 7.3 If the expected value is a RegExp object, the actual value is
// equivalent if it is also a RegExp object with the same source and
// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
} else if (util.isRegExp(actual) && util.isRegExp(expected)) {
return actual.source === expected.source &&
actual.global === expected.global &&
actual.multiline === expected.multiline &&
actual.lastIndex === expected.lastIndex &&
actual.ignoreCase === expected.ignoreCase;
// 7.4. Other pairs that do not both pass typeof value == 'object',
// equivalence is determined by ==.
} else if ((actual === null || typeof actual !== 'object') &&
(expected === null || typeof expected !== 'object')) {
return strict ? actual === expected : actual == expected;
// If both values are instances of typed arrays, wrap their underlying
// ArrayBuffers in a Buffer each to increase performance
// This optimization requires the arrays to have the same type as checked by
// Object.prototype.toString (aka pToString). Never perform binary
// comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
// bit patterns are not identical.
} else if (isView(actual) && isView(expected) &&
pToString(actual) === pToString(expected) &&
!(actual instanceof Float32Array ||
actual instanceof Float64Array)) {
return compare(new Uint8Array(actual.buffer),
new Uint8Array(expected.buffer)) === 0;
// 7.5 For all other Object pairs, including Array objects, equivalence is
// determined by having the same number of owned properties (as verified
// with Object.prototype.hasOwnProperty.call), the same set of keys
// (although not necessarily the same order), equivalent values for every
// corresponding key, and an identical 'prototype' property. Note: this
// accounts for both named and indexed properties on Arrays.
} else if (isBuffer(actual) !== isBuffer(expected)) {
return false;
} else {
memos = memos || {actual: [], expected: []};
var actualIndex = memos.actual.indexOf(actual);
if (actualIndex !== -1) {
if (actualIndex === memos.expected.indexOf(expected)) {
return true;
}
}
memos.actual.push(actual);
memos.expected.push(expected);
return objEquiv(actual, expected, strict, memos);
}
}
function isArguments(object) {
return Object.prototype.toString.call(object) == '[object Arguments]';
}
function objEquiv(a, b, strict, actualVisitedObjects) {
if (a === null || a === undefined || b === null || b === undefined)
return false;
// if one is a primitive, the other must be same
if (util.isPrimitive(a) || util.isPrimitive(b))
return a === b;
if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
return false;
var aIsArgs = isArguments(a);
var bIsArgs = isArguments(b);
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
return false;
if (aIsArgs) {
a = pSlice.call(a);
b = pSlice.call(b);
return _deepEqual(a, b, strict);
}
var ka = objectKeys(a);
var kb = objectKeys(b);
var key, i;
// having the same number of owned properties (keys incorporates
// hasOwnProperty)
if (ka.length !== kb.length)
return false;
//the same set of keys (although not necessarily the same order),
ka.sort();
kb.sort();
//~~~cheap key test
for (i = ka.length - 1; i >= 0; i--) {
if (ka[i] !== kb[i])
return false;
}
//equivalent values for every corresponding key, and
//~~~possibly expensive deep test
for (i = ka.length - 1; i >= 0; i--) {
key = ka[i];
if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
return false;
}
return true;
}
// 8. The non-equivalence assertion tests for any deep inequality.
// assert.notDeepEqual(actual, expected, message_opt);
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
if (_deepEqual(actual, expected, false)) {
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
}
};
assert.notDeepStrictEqual = notDeepStrictEqual;
function notDeepStrictEqual(actual, expected, message) {
if (_deepEqual(actual, expected, true)) {
fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
}
}
// 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt);
assert.strictEqual = function strictEqual(actual, expected, message) {
if (actual !== expected) {
fail(actual, expected, message, '===', assert.strictEqual);
}
};
// 10. The strict non-equality assertion tests for strict inequality, as
// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
if (actual === expected) {
fail(actual, expected, message, '!==', assert.notStrictEqual);
}
};
function expectedException(actual, expected) {
if (!actual || !expected) {
return false;
}
if (Object.prototype.toString.call(expected) == '[object RegExp]') {
return expected.test(actual);
}
try {
if (actual instanceof expected) {
return true;
}
} catch (e) {
// Ignore. The instanceof check doesn't work for arrow functions.
}
if (Error.isPrototypeOf(expected)) {
return false;
}
return expected.call({}, actual) === true;
}
function _tryBlock(block) {
var error;
try {
block();
} catch (e) {
error = e;
}
return error;
}
function _throws(shouldThrow, block, expected, message) {
var actual;
if (typeof block !== 'function') {
throw new TypeError('"block" argument must be a function');
}
if (typeof expected === 'string') {
message = expected;
expected = null;
}
actual = _tryBlock(block);
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
(message ? ' ' + message : '.');
if (shouldThrow && !actual) {
fail(actual, expected, 'Missing expected exception' + message);
}
var userProvidedMessage = typeof message === 'string';
var isUnwantedException = !shouldThrow && util.isError(actual);
var isUnexpectedException = !shouldThrow && actual && !expected;
if ((isUnwantedException &&
userProvidedMessage &&
expectedException(actual, expected)) ||
isUnexpectedException) {
fail(actual, expected, 'Got unwanted exception' + message);
}
if ((shouldThrow && actual && expected &&
!expectedException(actual, expected)) || (!shouldThrow && actual)) {
throw actual;
}
}
// 11. Expected to throw an error:
// assert.throws(block, Error_opt, message_opt);
assert.throws = function(block, /*optional*/error, /*optional*/message) {
_throws(true, block, error, message);
};
// EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
_throws(false, block, error, message);
};
assert.ifError = function(err) { if (err) throw err; };
var objectKeys = Object.keys || function (obj) {
var keys = [];
for (var key in obj) {
if (hasOwn.call(obj, key)) keys.push(key);
}
return keys;
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const luaconf = __webpack_require__(18);
// To avoid charCodeAt everywhere
const char = [];
for (let i = 0; i < 127; i++)
char[String.fromCharCode(i)] = i;
module.exports.char = char;
/* mark for precompiled code ('<esc>Lua') */
const LUA_SIGNATURE = "\x1bLua";
const LUA_VERSION_MAJOR = "5";
const LUA_VERSION_MINOR = "3";
const LUA_VERSION_NUM = 503;
const LUA_VERSION_RELEASE = "4";
const LUA_VERSION = "Lua " + LUA_VERSION_MAJOR + "." + LUA_VERSION_MINOR;
const LUA_RELEASE = LUA_VERSION + "." + LUA_VERSION_RELEASE;
const LUA_COPYRIGHT = LUA_RELEASE + " Copyright (C) 1994-2017 Lua.org, PUC-Rio";
const LUA_AUTHORS = "R. Ierusalimschy, L. H. de Figueiredo, W. Celes";
const FENGARI_VERSION_MAJOR = "0";
const FENGARI_VERSION_MINOR = "0";
const FENGARI_VERSION_NUM = 1;
const FENGARI_VERSION_RELEASE = "1";
const FENGARI_VERSION = "Fengari " + FENGARI_VERSION_MAJOR + "." + FENGARI_VERSION_MINOR;
const FENGARI_RELEASE = FENGARI_VERSION + "." + FENGARI_VERSION_RELEASE;
const FENGARI_AUTHORS = "B. Giannangeli, Daurnimator";
const FENGARI_COPYRIGHT = FENGARI_RELEASE + " Copyright (C) 2017 " + FENGARI_AUTHORS + "\nBased on: " + LUA_COPYRIGHT;
const LUA_VERSUFFIX = "_" + LUA_VERSION_MAJOR + "_" + LUA_VERSION_MINOR;
const LUA_INIT_VAR = "LUA_INIT";
const LUA_INITVARVERSION = LUA_INIT_VAR + LUA_VERSUFFIX;
const thread_status = {
LUA_OK: 0,
LUA_YIELD: 1,
LUA_ERRRUN: 2,
LUA_ERRSYNTAX: 3,
LUA_ERRMEM: 4,
LUA_ERRGCMM: 5,
LUA_ERRERR: 6
};
const constant_types = {
LUA_TNONE: -1,
LUA_TNIL: 0,
LUA_TBOOLEAN: 1,
LUA_TLIGHTUSERDATA: 2,
LUA_TNUMBER: 3,
LUA_TSTRING: 4,
LUA_TTABLE: 5,
LUA_TFUNCTION: 6,
LUA_TUSERDATA: 7,
LUA_TTHREAD: 8,
LUA_NUMTAGS: 9
};
constant_types.LUA_TSHRSTR = constant_types.LUA_TSTRING | (0 << 4); /* short strings */
constant_types.LUA_TLNGSTR = constant_types.LUA_TSTRING | (1 << 4); /* long strings */
constant_types.LUA_TNUMFLT = constant_types.LUA_TNUMBER | (0 << 4); /* float numbers */
constant_types.LUA_TNUMINT = constant_types.LUA_TNUMBER | (1 << 4); /* integer numbers */
constant_types.LUA_TLCL = constant_types.LUA_TFUNCTION | (0 << 4); /* Lua closure */
constant_types.LUA_TLCF = constant_types.LUA_TFUNCTION | (1 << 4); /* light C function */
constant_types.LUA_TCCL = constant_types.LUA_TFUNCTION | (2 << 4); /* C closure */
const CT = constant_types;
/*
** Comparison and arithmetic functions
*/
const LUA_OPADD = 0; /* ORDER TM, ORDER OP */
const LUA_OPSUB = 1;
const LUA_OPMUL = 2;
const LUA_OPMOD = 3;
const LUA_OPPOW = 4;
const LUA_OPDIV = 5;
const LUA_OPIDIV = 6;
const LUA_OPBAND = 7;
const LUA_OPBOR = 8;
const LUA_OPBXOR = 9;
const LUA_OPSHL = 10;
const LUA_OPSHR = 11;
const LUA_OPUNM = 12;
const LUA_OPBNOT = 13;
const LUA_OPEQ = 0;
const LUA_OPLT = 1;
const LUA_OPLE = 2;
const LUA_MINSTACK = 20;
const LUA_REGISTRYINDEX = -luaconf.LUAI_MAXSTACK - 1000;
const lua_upvalueindex = function(i) {
return LUA_REGISTRYINDEX - i;
};
/* predefined values in the registry */
const LUA_RIDX_MAINTHREAD = 1;
const LUA_RIDX_GLOBALS = 2;
const LUA_RIDX_LAST = LUA_RIDX_GLOBALS;
class lua_Debug {
constructor() {
this.event = NaN;
this.name = null; /* (n) */
this.namewhat = null; /* (n) 'global', 'local', 'field', 'method' */
this.what = null; /* (S) 'Lua', 'C', 'main', 'tail' */
this.source = null; /* (S) */
this.currentline = NaN; /* (l) */
this.linedefined = NaN; /* (S) */
this.lastlinedefined = NaN; /* (S) */
this.nups = NaN; /* (u) number of upvalues */
this.nparams = NaN; /* (u) number of parameters */
this.isvararg = NaN; /* (u) */
this.istailcall = NaN; /* (t) */
this.short_src = null; /* (S) */
/* private part */
this.i_ci = null; /* active function */
}
}
const is_luastring = function(s) {
return Array.isArray(s);
};
const to_jsstring = function(value, from, to) {
assert(is_luastring(value), "jsstring expect a array of bytes");
let u0, u1, u2, u3, u4, u5;
let idx = 0;
value = value.slice(from ? from : 0, to);
var str = '';
while (1) {
// For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
u0 = value[idx++];
if (u0 === 0) { str += "\0"; continue; } // Lua string embed '\0'
if (!u0) return str;
if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
u1 = value[idx++] & 63;
if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
u2 = value[idx++] & 63;
if ((u0 & 0xF0) == 0xE0) {
u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
} else {
u3 = value[idx++] & 63;
if ((u0 & 0xF8) == 0xF0) {
u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | u3;
} else {
u4 = value[idx++] & 63;
if ((u0 & 0xFC) == 0xF8) {
u0 = ((u0 & 3) << 24) | (u1 << 18) | (u2 << 12) | (u3 << 6) | u4;
} else {
u5 = value[idx++] & 63;
u0 = ((u0 & 1) << 30) | (u1 << 24) | (u2 << 18) | (u3 << 12) | (u4 << 6) | u5;
}
}
}
if (u0 < 0x10000) {
str += String.fromCharCode(u0);
} else {
var ch = u0 - 0x10000;
str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
}
}
};
const to_luastring_cache = {};
const to_luastring = function(str, cache) {
assert(typeof str === "string", "to_luastring expect a js string");
if (cache) {
let cached = to_luastring_cache[str];
if (is_luastring(cached)) return cached;
}
let outU8Array = [];
let outIdx = 0;
for (let i = 0; i < str.length; ++i) {
// See http://unicode.org/faq/utf_bom.html#utf16-3
// For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
let u = str.codePointAt(i);
if (u >= 0xD800) i++; // If it was a surrogate pair it used up two bytes
if (u <= 0x7F) {
outU8Array[outIdx++] = u;
} else if (u <= 0x7FF) {
outU8Array[outIdx++] = 0xC0 | (u >> 6);
outU8Array[outIdx++] = 0x80 | (u & 63);
} else if (u <= 0xFFFF) {
outU8Array[outIdx++] = 0xE0 | (u >> 12);
outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
outU8Array[outIdx++] = 0x80 | (u & 63);
} else if (u <= 0x1FFFFF) {
outU8Array[outIdx++] = 0xF0 | (u >> 18);
outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
outU8Array[outIdx++] = 0x80 | (u & 63);
} else if (u <= 0x3FFFFFF) {
outU8Array[outIdx++] = 0xF8 | (u >> 24);
outU8Array[outIdx++] = 0x80 | ((u >> 18) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
outU8Array[outIdx++] = 0x80 | (u & 63);
} else {
outU8Array[outIdx++] = 0xFC | (u >> 30);
outU8Array[outIdx++] = 0x80 | ((u >> 24) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 18) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
outU8Array[outIdx++] = 0x80 | (u & 63);
}
}
// Null-terminate the pointer to the buffer.
// outU8Array[outIdx] = 0;
if (cache) to_luastring_cache[str] = outU8Array;
return outU8Array;
};
/*
** Event codes
*/
const LUA_HOOKCALL = 0;
const LUA_HOOKRET = 1;
const LUA_HOOKLINE = 2;
const LUA_HOOKCOUNT = 3;
const LUA_HOOKTAILCALL = 4;
/*
** Event masks
*/
const LUA_MASKCALL = (1 << LUA_HOOKCALL);
const LUA_MASKRET = (1 << LUA_HOOKRET);
const LUA_MASKLINE = (1 << LUA_HOOKLINE);
const LUA_MASKCOUNT = (1 << LUA_HOOKCOUNT);
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
*/
const LUA_PATH_SEP = ";";
module.exports.LUA_PATH_SEP = LUA_PATH_SEP;
const LUA_PATH_MARK = "?";
module.exports.LUA_PATH_MARK = LUA_PATH_MARK;
const LUA_EXEC_DIR = "!";
module.exports.LUA_EXEC_DIR = LUA_EXEC_DIR;
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
** Lua libraries.
@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
** C libraries.
** CHANGE them if your machine has a non-conventional directory
** hierarchy or if you want to install your libraries in
** non-conventional directories.
*/
const LUA_VDIR = LUA_VERSION_MAJOR + "." + LUA_VERSION_MINOR;
module.exports.LUA_VDIR = LUA_VDIR;
if (true) {
const LUA_DIRSEP = "/";
module.exports.LUA_DIRSEP = LUA_DIRSEP;
const LUA_LDIR = "./lua/" + LUA_VDIR + "/";
module.exports.LUA_LDIR = LUA_LDIR;
const LUA_CDIR = "./lua/" + LUA_VDIR + "/";
module.exports.LUA_CDIR = LUA_CDIR;
const LUA_PATH_DEFAULT =
LUA_LDIR + "?.lua;" + LUA_LDIR + "?/init.lua;" +
LUA_CDIR + "?.lua;" + LUA_CDIR + "?/init.lua;" +
"./?.lua;./?/init.lua";
module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT;
const LUA_CPATH_DEFAULT =
LUA_CDIR + "?.js;" + LUA_CDIR + "loadall.js;./?.js";
module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT;
} else if (require('os').platform() === 'win32') {
const LUA_DIRSEP = "\\";
module.exports.LUA_DIRSEP = LUA_DIRSEP;
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
*/
const LUA_LDIR = "!\\lua\\";
module.exports.LUA_LDIR = LUA_LDIR;
const LUA_CDIR = "!\\";
module.exports.LUA_CDIR = LUA_CDIR;
const LUA_SHRDIR = "!\\..\\share\\lua\\" + LUA_VDIR + "\\";
module.exports.LUA_SHRDIR = LUA_SHRDIR;
const LUA_PATH_DEFAULT =
LUA_LDIR + "?.lua;" + LUA_LDIR + "?\\init.lua;" +
LUA_CDIR + "?.lua;" + LUA_CDIR + "?\\init.lua;" +
LUA_SHRDIR + "?.lua;" + LUA_SHRDIR + "?\\init.lua;" +
".\\?.lua;.\\?\\init.lua";
module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT;
const LUA_CPATH_DEFAULT =
LUA_CDIR + "?.dll;" +
LUA_CDIR + "..\\lib\\lua\\" + LUA_VDIR + "\\?.dll;" +
LUA_CDIR + "loadall.dll;.\\?.dll";
module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT;
} else {
const LUA_DIRSEP = "/";
module.exports.LUA_DIRSEP = LUA_DIRSEP;
const LUA_ROOT = "/usr/local/";
module.exports.LUA_ROOT = LUA_ROOT;
const LUA_LDIR = LUA_ROOT + "share/lua/" + LUA_VDIR + "/";
module.exports.LUA_LDIR = LUA_LDIR;
const LUA_CDIR = LUA_ROOT + "lib/lua/" + LUA_VDIR + "/";
module.exports.LUA_CDIR = LUA_CDIR;
const LUA_PATH_DEFAULT =
LUA_LDIR + "?.lua;" + LUA_LDIR + "?/init.lua;" +
LUA_CDIR + "?.lua;" + LUA_CDIR + "?/init.lua;" +
"./?.lua;./?/init.lua";
module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT;
const LUA_CPATH_DEFAULT =
LUA_CDIR + "?.so;" + LUA_CDIR + "loadall.so;./?.so";
module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT;
}
module.exports.CT = CT;
module.exports.FENGARI_AUTHORS = FENGARI_AUTHORS;
module.exports.FENGARI_COPYRIGHT = FENGARI_COPYRIGHT;
module.exports.FENGARI_RELEASE = FENGARI_RELEASE;
module.exports.FENGARI_VERSION = FENGARI_VERSION;
module.exports.FENGARI_VERSION_MAJOR = FENGARI_VERSION_MAJOR;
module.exports.FENGARI_VERSION_MINOR = FENGARI_VERSION_MINOR;
module.exports.FENGARI_VERSION_NUM = FENGARI_VERSION_NUM;
module.exports.FENGARI_VERSION_RELEASE = FENGARI_VERSION_RELEASE;
module.exports.LUA_AUTHORS = LUA_AUTHORS;
module.exports.LUA_COPYRIGHT = LUA_COPYRIGHT;
module.exports.LUA_HOOKCALL = LUA_HOOKCALL;
module.exports.LUA_HOOKCOUNT = LUA_HOOKCOUNT;
module.exports.LUA_HOOKLINE = LUA_HOOKLINE;
module.exports.LUA_HOOKRET = LUA_HOOKRET;
module.exports.LUA_HOOKTAILCALL = LUA_HOOKTAILCALL;
module.exports.LUA_INITVARVERSION = LUA_INITVARVERSION;
module.exports.LUA_INIT_VAR = LUA_INIT_VAR;
module.exports.LUA_MASKCALL = LUA_MASKCALL;
module.exports.LUA_MASKCOUNT = LUA_MASKCOUNT;
module.exports.LUA_MASKLINE = LUA_MASKLINE;
module.exports.LUA_MASKRET = LUA_MASKRET;
module.exports.LUA_MINSTACK = LUA_MINSTACK;
module.exports.LUA_MULTRET = -1;
module.exports.LUA_OPADD = LUA_OPADD;
module.exports.LUA_OPBAND = LUA_OPBAND;
module.exports.LUA_OPBNOT = LUA_OPBNOT;
module.exports.LUA_OPBOR = LUA_OPBOR;
module.exports.LUA_OPBXOR = LUA_OPBXOR;
module.exports.LUA_OPDIV = LUA_OPDIV;
module.exports.LUA_OPEQ = LUA_OPEQ;
module.exports.LUA_OPIDIV = LUA_OPIDIV;
module.exports.LUA_OPLE = LUA_OPLE;
module.exports.LUA_OPLT = LUA_OPLT;
module.exports.LUA_OPMOD = LUA_OPMOD;
module.exports.LUA_OPMUL = LUA_OPMUL;
module.exports.LUA_OPPOW = LUA_OPPOW;
module.exports.LUA_OPSHL = LUA_OPSHL;
module.exports.LUA_OPSHR = LUA_OPSHR;
module.exports.LUA_OPSUB = LUA_OPSUB;
module.exports.LUA_OPUNM = LUA_OPUNM;
module.exports.LUA_REGISTRYINDEX = LUA_REGISTRYINDEX;
module.exports.LUA_RELEASE = LUA_RELEASE;
module.exports.LUA_RIDX_GLOBALS = LUA_RIDX_GLOBALS;
module.exports.LUA_RIDX_LAST = LUA_RIDX_LAST;
module.exports.LUA_RIDX_MAINTHREAD = LUA_RIDX_MAINTHREAD;
module.exports.LUA_SIGNATURE = LUA_SIGNATURE;
module.exports.LUA_VERSION = LUA_VERSION;
module.exports.LUA_VERSION_MAJOR = LUA_VERSION_MAJOR;
module.exports.LUA_VERSION_MINOR = LUA_VERSION_MINOR;
module.exports.LUA_VERSION_NUM = LUA_VERSION_NUM;
module.exports.LUA_VERSION_RELEASE = LUA_VERSION_RELEASE;
module.exports.LUA_VERSUFFIX = LUA_VERSUFFIX;
module.exports.constant_types = constant_types;
module.exports.lua_Debug = lua_Debug;
module.exports.lua_upvalueindex = lua_upvalueindex;
module.exports.thread_status = thread_status;
module.exports.is_luastring = is_luastring;
module.exports.to_jsstring = to_jsstring;
module.exports.to_luastring = to_luastring;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const luaconf = __webpack_require__(22);
// To avoid charCodeAt everywhere
const char = [];
for (let i = 0; i < 127; i++)
char[String.fromCharCode(i)] = i;
module.exports.char = char;
/* mark for precompiled code ('<esc>Lua') */
const LUA_SIGNATURE = "\x1bLua";
const LUA_VERSION_MAJOR = "5";
const LUA_VERSION_MINOR = "3";
const LUA_VERSION_NUM = 503;
const LUA_VERSION_RELEASE = "4";
const LUA_VERSION = "Lua " + LUA_VERSION_MAJOR + "." + LUA_VERSION_MINOR;
const LUA_RELEASE = LUA_VERSION + "." + LUA_VERSION_RELEASE;
const LUA_COPYRIGHT = LUA_RELEASE + " Copyright (C) 1994-2017 Lua.org, PUC-Rio";
const LUA_AUTHORS = "R. Ierusalimschy, L. H. de Figueiredo, W. Celes";
const FENGARI_VERSION_MAJOR = "0";
const FENGARI_VERSION_MINOR = "0";
const FENGARI_VERSION_NUM = 1;
const FENGARI_VERSION_RELEASE = "1";
const FENGARI_VERSION = "Fengari " + FENGARI_VERSION_MAJOR + "." + FENGARI_VERSION_MINOR;
const FENGARI_RELEASE = FENGARI_VERSION + "." + FENGARI_VERSION_RELEASE;
const FENGARI_AUTHORS = "B. Giannangeli, Daurnimator";
const FENGARI_COPYRIGHT = FENGARI_RELEASE + " Copyright (C) 2017 " + FENGARI_AUTHORS + "\nBased on: " + LUA_COPYRIGHT;
const LUA_VERSUFFIX = "_" + LUA_VERSION_MAJOR + "_" + LUA_VERSION_MINOR;
const LUA_INIT_VAR = "LUA_INIT";
const LUA_INITVARVERSION = LUA_INIT_VAR + LUA_VERSUFFIX;
const thread_status = {
LUA_OK: 0,
LUA_YIELD: 1,
LUA_ERRRUN: 2,
LUA_ERRSYNTAX: 3,
LUA_ERRMEM: 4,
LUA_ERRGCMM: 5,
LUA_ERRERR: 6
};
const constant_types = {
LUA_TNONE: -1,
LUA_TNIL: 0,
LUA_TBOOLEAN: 1,
LUA_TLIGHTUSERDATA: 2,
LUA_TNUMBER: 3,
LUA_TSTRING: 4,
LUA_TTABLE: 5,
LUA_TFUNCTION: 6,
LUA_TUSERDATA: 7,
LUA_TTHREAD: 8,
LUA_NUMTAGS: 9
};
constant_types.LUA_TSHRSTR = constant_types.LUA_TSTRING | (0 << 4); /* short strings */
constant_types.LUA_TLNGSTR = constant_types.LUA_TSTRING | (1 << 4); /* long strings */
constant_types.LUA_TNUMFLT = constant_types.LUA_TNUMBER | (0 << 4); /* float numbers */
constant_types.LUA_TNUMINT = constant_types.LUA_TNUMBER | (1 << 4); /* integer numbers */
constant_types.LUA_TLCL = constant_types.LUA_TFUNCTION | (0 << 4); /* Lua closure */
constant_types.LUA_TLCF = constant_types.LUA_TFUNCTION | (1 << 4); /* light C function */
constant_types.LUA_TCCL = constant_types.LUA_TFUNCTION | (2 << 4); /* C closure */
const CT = constant_types;
/*
** Comparison and arithmetic functions
*/
const LUA_OPADD = 0; /* ORDER TM, ORDER OP */
const LUA_OPSUB = 1;
const LUA_OPMUL = 2;
const LUA_OPMOD = 3;
const LUA_OPPOW = 4;
const LUA_OPDIV = 5;
const LUA_OPIDIV = 6;
const LUA_OPBAND = 7;
const LUA_OPBOR = 8;
const LUA_OPBXOR = 9;
const LUA_OPSHL = 10;
const LUA_OPSHR = 11;
const LUA_OPUNM = 12;
const LUA_OPBNOT = 13;
const LUA_OPEQ = 0;
const LUA_OPLT = 1;
const LUA_OPLE = 2;
const LUA_MINSTACK = 20;
const LUA_REGISTRYINDEX = -luaconf.LUAI_MAXSTACK - 1000;
const lua_upvalueindex = function(i) {
return LUA_REGISTRYINDEX - i;
};
/* predefined values in the registry */
const LUA_RIDX_MAINTHREAD = 1;
const LUA_RIDX_GLOBALS = 2;
const LUA_RIDX_LAST = LUA_RIDX_GLOBALS;
class lua_Debug {
constructor() {
this.event = NaN;
this.name = null; /* (n) */
this.namewhat = null; /* (n) 'global', 'local', 'field', 'method' */
this.what = null; /* (S) 'Lua', 'C', 'main', 'tail' */
this.source = null; /* (S) */
this.currentline = NaN; /* (l) */
this.linedefined = NaN; /* (S) */
this.lastlinedefined = NaN; /* (S) */
this.nups = NaN; /* (u) number of upvalues */
this.nparams = NaN; /* (u) number of parameters */
this.isvararg = NaN; /* (u) */
this.istailcall = NaN; /* (t) */
this.short_src = null; /* (S) */
/* private part */
this.i_ci = null; /* active function */
}
}
const is_luastring = function(s) {
return Array.isArray(s);
};
const to_jsstring = function(value, from, to) {
assert(is_luastring(value), "jsstring expect a array of bytes");
let u0, u1, u2, u3, u4, u5;
let idx = 0;
value = value.slice(from ? from : 0, to);
var str = '';
while (1) {
// For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
u0 = value[idx++];
if (u0 === 0) { str += "\0"; continue; } // Lua string embed '\0'
if (!u0) return str;
if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
u1 = value[idx++] & 63;
if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
u2 = value[idx++] & 63;
if ((u0 & 0xF0) == 0xE0) {
u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
} else {
u3 = value[idx++] & 63;
if ((u0 & 0xF8) == 0xF0) {
u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | u3;
} else {
u4 = value[idx++] & 63;
if ((u0 & 0xFC) == 0xF8) {
u0 = ((u0 & 3) << 24) | (u1 << 18) | (u2 << 12) | (u3 << 6) | u4;
} else {
u5 = value[idx++] & 63;
u0 = ((u0 & 1) << 30) | (u1 << 24) | (u2 << 18) | (u3 << 12) | (u4 << 6) | u5;
}
}
}
if (u0 < 0x10000) {
str += String.fromCharCode(u0);
} else {
var ch = u0 - 0x10000;
str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
}
}
};
const to_luastring_cache = {};
const to_luastring = function(str, cache) {
assert(typeof str === "string", "to_luastring expect a js string");
if (cache) {
let cached = to_luastring_cache[str];
if (is_luastring(cached)) return cached;
}
let outU8Array = [];
let outIdx = 0;
for (let i = 0; i < str.length; ++i) {
// See http://unicode.org/faq/utf_bom.html#utf16-3
// For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
let u = str.codePointAt(i);
if (u >= 0xD800) i++; // If it was a surrogate pair it used up two bytes
if (u <= 0x7F) {
outU8Array[outIdx++] = u;
} else if (u <= 0x7FF) {
outU8Array[outIdx++] = 0xC0 | (u >> 6);
outU8Array[outIdx++] = 0x80 | (u & 63);
} else if (u <= 0xFFFF) {
outU8Array[outIdx++] = 0xE0 | (u >> 12);
outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
outU8Array[outIdx++] = 0x80 | (u & 63);
} else if (u <= 0x1FFFFF) {
outU8Array[outIdx++] = 0xF0 | (u >> 18);
outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
outU8Array[outIdx++] = 0x80 | (u & 63);
} else if (u <= 0x3FFFFFF) {
outU8Array[outIdx++] = 0xF8 | (u >> 24);
outU8Array[outIdx++] = 0x80 | ((u >> 18) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
outU8Array[outIdx++] = 0x80 | (u & 63);
} else {
outU8Array[outIdx++] = 0xFC | (u >> 30);
outU8Array[outIdx++] = 0x80 | ((u >> 24) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 18) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
outU8Array[outIdx++] = 0x80 | (u & 63);
}
}
// Null-terminate the pointer to the buffer.
// outU8Array[outIdx] = 0;
if (cache) to_luastring_cache[str] = outU8Array;
return outU8Array;
};
/*
** Event codes
*/
const LUA_HOOKCALL = 0;
const LUA_HOOKRET = 1;
const LUA_HOOKLINE = 2;
const LUA_HOOKCOUNT = 3;
const LUA_HOOKTAILCALL = 4;
/*
** Event masks
*/
const LUA_MASKCALL = (1 << LUA_HOOKCALL);
const LUA_MASKRET = (1 << LUA_HOOKRET);
const LUA_MASKLINE = (1 << LUA_HOOKLINE);
const LUA_MASKCOUNT = (1 << LUA_HOOKCOUNT);
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
*/
const LUA_PATH_SEP = ";";
module.exports.LUA_PATH_SEP = LUA_PATH_SEP;
const LUA_PATH_MARK = "?";
module.exports.LUA_PATH_MARK = LUA_PATH_MARK;
const LUA_EXEC_DIR = "!";
module.exports.LUA_EXEC_DIR = LUA_EXEC_DIR;
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
** Lua libraries.
@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
** C libraries.
** CHANGE them if your machine has a non-conventional directory
** hierarchy or if you want to install your libraries in
** non-conventional directories.
*/
const LUA_VDIR = LUA_VERSION_MAJOR + "." + LUA_VERSION_MINOR;
module.exports.LUA_VDIR = LUA_VDIR;
if (true) {
const LUA_DIRSEP = "/";
module.exports.LUA_DIRSEP = LUA_DIRSEP;
const LUA_LDIR = "./lua/" + LUA_VDIR + "/";
module.exports.LUA_LDIR = LUA_LDIR;
const LUA_CDIR = "./lua/" + LUA_VDIR + "/";
module.exports.LUA_CDIR = LUA_CDIR;
const LUA_PATH_DEFAULT =
LUA_LDIR + "?.lua;" + LUA_LDIR + "?/init.lua;" +
LUA_CDIR + "?.lua;" + LUA_CDIR + "?/init.lua;" +
"./?.lua;./?/init.lua";
module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT;
const LUA_CPATH_DEFAULT =
LUA_CDIR + "?.js;" + LUA_CDIR + "loadall.js;./?.js";
module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT;
} else if (require('os').platform() === 'win32') {
const LUA_DIRSEP = "\\";
module.exports.LUA_DIRSEP = LUA_DIRSEP;
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
*/
const LUA_LDIR = "!\\lua\\";
module.exports.LUA_LDIR = LUA_LDIR;
const LUA_CDIR = "!\\";
module.exports.LUA_CDIR = LUA_CDIR;
const LUA_SHRDIR = "!\\..\\share\\lua\\" + LUA_VDIR + "\\";
module.exports.LUA_SHRDIR = LUA_SHRDIR;
const LUA_PATH_DEFAULT =
LUA_LDIR + "?.lua;" + LUA_LDIR + "?\\init.lua;" +
LUA_CDIR + "?.lua;" + LUA_CDIR + "?\\init.lua;" +
LUA_SHRDIR + "?.lua;" + LUA_SHRDIR + "?\\init.lua;" +
".\\?.lua;.\\?\\init.lua";
module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT;
const LUA_CPATH_DEFAULT =
LUA_CDIR + "?.dll;" +
LUA_CDIR + "..\\lib\\lua\\" + LUA_VDIR + "\\?.dll;" +
LUA_CDIR + "loadall.dll;.\\?.dll";
module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT;
} else {
const LUA_DIRSEP = "/";
module.exports.LUA_DIRSEP = LUA_DIRSEP;
const LUA_ROOT = "/usr/local/";
module.exports.LUA_ROOT = LUA_ROOT;
const LUA_LDIR = LUA_ROOT + "share/lua/" + LUA_VDIR + "/";
module.exports.LUA_LDIR = LUA_LDIR;
const LUA_CDIR = LUA_ROOT + "lib/lua/" + LUA_VDIR + "/";
module.exports.LUA_CDIR = LUA_CDIR;
const LUA_PATH_DEFAULT =
LUA_LDIR + "?.lua;" + LUA_LDIR + "?/init.lua;" +
LUA_CDIR + "?.lua;" + LUA_CDIR + "?/init.lua;" +
"./?.lua;./?/init.lua";
module.exports.LUA_PATH_DEFAULT = LUA_PATH_DEFAULT;
const LUA_CPATH_DEFAULT =
LUA_CDIR + "?.so;" + LUA_CDIR + "loadall.so;./?.so";
module.exports.LUA_CPATH_DEFAULT = LUA_CPATH_DEFAULT;
}
module.exports.CT = CT;
module.exports.FENGARI_AUTHORS = FENGARI_AUTHORS;
module.exports.FENGARI_COPYRIGHT = FENGARI_COPYRIGHT;
module.exports.FENGARI_RELEASE = FENGARI_RELEASE;
module.exports.FENGARI_VERSION = FENGARI_VERSION;
module.exports.FENGARI_VERSION_MAJOR = FENGARI_VERSION_MAJOR;
module.exports.FENGARI_VERSION_MINOR = FENGARI_VERSION_MINOR;
module.exports.FENGARI_VERSION_NUM = FENGARI_VERSION_NUM;
module.exports.FENGARI_VERSION_RELEASE = FENGARI_VERSION_RELEASE;
module.exports.LUA_AUTHORS = LUA_AUTHORS;
module.exports.LUA_COPYRIGHT = LUA_COPYRIGHT;
module.exports.LUA_HOOKCALL = LUA_HOOKCALL;
module.exports.LUA_HOOKCOUNT = LUA_HOOKCOUNT;
module.exports.LUA_HOOKLINE = LUA_HOOKLINE;
module.exports.LUA_HOOKRET = LUA_HOOKRET;
module.exports.LUA_HOOKTAILCALL = LUA_HOOKTAILCALL;
module.exports.LUA_INITVARVERSION = LUA_INITVARVERSION;
module.exports.LUA_INIT_VAR = LUA_INIT_VAR;
module.exports.LUA_MASKCALL = LUA_MASKCALL;
module.exports.LUA_MASKCOUNT = LUA_MASKCOUNT;
module.exports.LUA_MASKLINE = LUA_MASKLINE;
module.exports.LUA_MASKRET = LUA_MASKRET;
module.exports.LUA_MINSTACK = LUA_MINSTACK;
module.exports.LUA_MULTRET = -1;
module.exports.LUA_OPADD = LUA_OPADD;
module.exports.LUA_OPBAND = LUA_OPBAND;
module.exports.LUA_OPBNOT = LUA_OPBNOT;
module.exports.LUA_OPBOR = LUA_OPBOR;
module.exports.LUA_OPBXOR = LUA_OPBXOR;
module.exports.LUA_OPDIV = LUA_OPDIV;
module.exports.LUA_OPEQ = LUA_OPEQ;
module.exports.LUA_OPIDIV = LUA_OPIDIV;
module.exports.LUA_OPLE = LUA_OPLE;
module.exports.LUA_OPLT = LUA_OPLT;
module.exports.LUA_OPMOD = LUA_OPMOD;
module.exports.LUA_OPMUL = LUA_OPMUL;
module.exports.LUA_OPPOW = LUA_OPPOW;
module.exports.LUA_OPSHL = LUA_OPSHL;
module.exports.LUA_OPSHR = LUA_OPSHR;
module.exports.LUA_OPSUB = LUA_OPSUB;
module.exports.LUA_OPUNM = LUA_OPUNM;
module.exports.LUA_REGISTRYINDEX = LUA_REGISTRYINDEX;
module.exports.LUA_RELEASE = LUA_RELEASE;
module.exports.LUA_RIDX_GLOBALS = LUA_RIDX_GLOBALS;
module.exports.LUA_RIDX_LAST = LUA_RIDX_LAST;
module.exports.LUA_RIDX_MAINTHREAD = LUA_RIDX_MAINTHREAD;
module.exports.LUA_SIGNATURE = LUA_SIGNATURE;
module.exports.LUA_VERSION = LUA_VERSION;
module.exports.LUA_VERSION_MAJOR = LUA_VERSION_MAJOR;
module.exports.LUA_VERSION_MINOR = LUA_VERSION_MINOR;
module.exports.LUA_VERSION_NUM = LUA_VERSION_NUM;
module.exports.LUA_VERSION_RELEASE = LUA_VERSION_RELEASE;
module.exports.LUA_VERSUFFIX = LUA_VERSUFFIX;
module.exports.constant_types = constant_types;
module.exports.lua_Debug = lua_Debug;
module.exports.lua_upvalueindex = lua_upvalueindex;
module.exports.thread_status = thread_status;
module.exports.is_luastring = is_luastring;
module.exports.to_jsstring = to_jsstring;
module.exports.to_luastring = to_luastring;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const defs = __webpack_require__(1);
const lapi = __webpack_require__(37);
const ldebug = __webpack_require__(19);
const ldo = __webpack_require__(12);
const lstate = __webpack_require__(21);
module.exports.FENGARI_AUTHORS = defs.FENGARI_AUTHORS;
module.exports.FENGARI_COPYRIGHT = defs.FENGARI_COPYRIGHT;
module.exports.FENGARI_RELEASE = defs.FENGARI_RELEASE;
module.exports.FENGARI_VERSION = defs.FENGARI_VERSION;
module.exports.FENGARI_VERSION_MAJOR = defs.FENGARI_VERSION_MAJOR;
module.exports.FENGARI_VERSION_MINOR = defs.FENGARI_VERSION_MINOR;
module.exports.FENGARI_VERSION_NUM = defs.FENGARI_VERSION_NUM;
module.exports.FENGARI_VERSION_RELEASE = defs.FENGARI_VERSION_RELEASE;
module.exports.LUA_AUTHORS = defs.LUA_AUTHORS;
module.exports.LUA_COPYRIGHT = defs.LUA_COPYRIGHT;
module.exports.LUA_ERRERR = defs.thread_status.LUA_ERRERR;
module.exports.LUA_ERRGCMM = defs.thread_status.LUA_ERRGCMM;
module.exports.LUA_ERRMEM = defs.thread_status.LUA_ERRMEM;
module.exports.LUA_ERRRUN = defs.thread_status.LUA_ERRRUN;
module.exports.LUA_ERRSYNTAX = defs.thread_status.LUA_ERRSYNTAX;
module.exports.LUA_HOOKCALL = defs.LUA_HOOKCALL;
module.exports.LUA_HOOKCOUNT = defs.LUA_HOOKCOUNT;
module.exports.LUA_HOOKLINE = defs.LUA_HOOKLINE;
module.exports.LUA_HOOKRET = defs.LUA_HOOKRET;
module.exports.LUA_HOOKTAILCALL = defs.LUA_HOOKTAILCALL;
module.exports.LUA_INITVARVERSION = defs.LUA_INITVARVERSION;
module.exports.LUA_INIT_VAR = defs.LUA_INIT_VAR;
module.exports.LUA_MASKCALL = defs.LUA_MASKCALL;
module.exports.LUA_MASKCOUNT = defs.LUA_MASKCOUNT;
module.exports.LUA_MASKLINE = defs.LUA_MASKLINE;
module.exports.LUA_MASKRET = defs.LUA_MASKRET;
module.exports.LUA_MINSTACK = defs.LUA_MINSTACK;
module.exports.LUA_MULTRET = defs.LUA_MULTRET;
module.exports.LUA_NUMTAGS = defs.LUA_NUMTAGS;
module.exports.LUA_OK = defs.thread_status.LUA_OK;
module.exports.LUA_OPADD = defs.LUA_OPADD;
module.exports.LUA_OPBAND = defs.LUA_OPBAND;
module.exports.LUA_OPBNOT = defs.LUA_OPBNOT;
module.exports.LUA_OPBOR = defs.LUA_OPBOR;
module.exports.LUA_OPBXOR = defs.LUA_OPBXOR;
module.exports.LUA_OPDIV = defs.LUA_OPDIV;
module.exports.LUA_OPEQ = defs.LUA_OPEQ;
module.exports.LUA_OPIDIV = defs.LUA_OPIDIV;
module.exports.LUA_OPLE = defs.LUA_OPLE;
module.exports.LUA_OPLT = defs.LUA_OPLT;
module.exports.LUA_OPMOD = defs.LUA_OPMOD;
module.exports.LUA_OPMUL = defs.LUA_OPMUL;
module.exports.LUA_OPPOW = defs.LUA_OPPOW;
module.exports.LUA_OPSHL = defs.LUA_OPSHL;
module.exports.LUA_OPSHR = defs.LUA_OPSHR;
module.exports.LUA_OPSUB = defs.LUA_OPSUB;
module.exports.LUA_OPUNM = defs.LUA_OPUNM;
module.exports.LUA_REGISTRYINDEX = defs.LUA_REGISTRYINDEX;
module.exports.LUA_RELEASE = defs.LUA_RELEASE;
module.exports.LUA_RIDX_GLOBALS = defs.LUA_RIDX_GLOBALS;
module.exports.LUA_RIDX_LAST = defs.LUA_RIDX_LAST;
module.exports.LUA_RIDX_MAINTHREAD = defs.LUA_RIDX_MAINTHREAD;
module.exports.LUA_SIGNATURE = defs.LUA_SIGNATURE;
module.exports.LUA_TNONE = defs.CT.LUA_TNONE;
module.exports.LUA_TNIL = defs.CT.LUA_TNIL;
module.exports.LUA_TBOOLEAN = defs.CT.LUA_TBOOLEAN;
module.exports.LUA_TLIGHTUSERDATA = defs.CT.LUA_TLIGHTUSERDATA;
module.exports.LUA_TNUMBER = defs.CT.LUA_TNUMBER;
module.exports.LUA_TSTRING = defs.CT.LUA_TSTRING;
module.exports.LUA_TTABLE = defs.CT.LUA_TTABLE;
module.exports.LUA_TFUNCTION = defs.CT.LUA_TFUNCTION;
module.exports.LUA_TUSERDATA = defs.CT.LUA_TUSERDATA;
module.exports.LUA_TTHREAD = defs.CT.LUA_TTHREAD;
module.exports.LUA_VERSION = defs.LUA_VERSION;
module.exports.LUA_VERSION_MAJOR = defs.LUA_VERSION_MAJOR;
module.exports.LUA_VERSION_MINOR = defs.LUA_VERSION_MINOR;
module.exports.LUA_VERSION_NUM = defs.LUA_VERSION_NUM;
module.exports.LUA_VERSION_RELEASE = defs.LUA_VERSION_RELEASE;
module.exports.LUA_VERSUFFIX = defs.LUA_VERSUFFIX;
module.exports.LUA_YIELD = defs.thread_status.LUA_YIELD;
module.exports.lua_Debug = defs.lua_Debug;
module.exports.lua_upvalueindex = defs.lua_upvalueindex;
module.exports.to_jsstring = defs.to_jsstring;
module.exports.to_luastring = defs.to_luastring;
module.exports.LUA_CDIR = defs.LUA_CDIR;
module.exports.LUA_CPATH_DEFAULT = defs.LUA_CPATH_DEFAULT;
module.exports.LUA_EXEC_DIR = defs.LUA_EXEC_DIR;
module.exports.LUA_LDIR = defs.LUA_LDIR;
module.exports.LUA_PATH_DEFAULT = defs.LUA_PATH_DEFAULT;
module.exports.LUA_PATH_MARK = defs.LUA_PATH_MARK;
module.exports.LUA_PATH_SEP = defs.LUA_PATH_SEP;
module.exports.LUA_ROOT = defs.LUA_ROOT;
module.exports.LUA_SHRDIR = defs.LUA_SHRDIR;
module.exports.LUA_VDIR = defs.LUA_VDIR;
module.exports.LUA_DIRSEP = defs.LUA_DIRSEP;
module.exports.lua_absindex = lapi.lua_absindex;
module.exports.lua_arith = lapi.lua_arith;
module.exports.lua_atpanic = lapi.lua_atpanic;
module.exports.lua_atnativeerror = lapi.lua_atnativeerror;
module.exports.lua_call = lapi.lua_call;
module.exports.lua_callk = lapi.lua_callk;
module.exports.lua_checkstack = lapi.lua_checkstack;
module.exports.lua_close = lstate.lua_close;
module.exports.lua_compare = lapi.lua_compare;
module.exports.lua_concat = lapi.lua_concat;
module.exports.lua_copy = lapi.lua_copy;
module.exports.lua_createtable = lapi.lua_createtable;
module.exports.lua_dump = lapi.lua_dump;
module.exports.lua_error = lapi.lua_error;
module.exports.lua_gc = lapi.lua_gc;
module.exports.lua_getallocf = lapi.lua_getallocf;
module.exports.lua_getextraspace = lapi.lua_getextraspace;
module.exports.lua_getfield = lapi.lua_getfield;
module.exports.lua_getglobal = lapi.lua_getglobal;
module.exports.lua_gethook = ldebug.lua_gethook;
module.exports.lua_gethookcount = ldebug.lua_gethookcount;
module.exports.lua_gethookmask = ldebug.lua_gethookmask;
module.exports.lua_geti = lapi.lua_geti;
module.exports.lua_getinfo = ldebug.lua_getinfo;
module.exports.lua_getlocal = ldebug.lua_getlocal;
module.exports.lua_getmetatable = lapi.lua_getmetatable;
module.exports.lua_getstack = ldebug.lua_getstack;
module.exports.lua_gettable = lapi.lua_gettable;
module.exports.lua_gettop = lapi.lua_gettop;
module.exports.lua_getupvalue = lapi.lua_getupvalue;
module.exports.lua_getuservalue = lapi.lua_getuservalue;
module.exports.lua_insert = lapi.lua_insert;
module.exports.lua_isboolean = lapi.lua_isboolean;
module.exports.lua_iscfunction = lapi.lua_iscfunction;
module.exports.lua_isfunction = lapi.lua_isfunction;
module.exports.lua_isinteger = lapi.lua_isinteger;
module.exports.lua_islightuserdata = lapi.lua_islightuserdata;
module.exports.lua_isnil = lapi.lua_isnil;
module.exports.lua_isnone = lapi.lua_isnone;
module.exports.lua_isnoneornil = lapi.lua_isnoneornil;
module.exports.lua_isnumber = lapi.lua_isnumber;
module.exports.lua_isproxy = lapi.lua_isproxy;
module.exports.lua_isstring = lapi.lua_isstring;
module.exports.lua_istable = lapi.lua_istable;
module.exports.lua_isthread = lapi.lua_isthread;
module.exports.lua_isuserdata = lapi.lua_isuserdata;
module.exports.lua_isyieldable = ldo.lua_isyieldable;
module.exports.lua_len = lapi.lua_len;
module.exports.lua_load = lapi.lua_load;
module.exports.lua_newstate = lstate.lua_newstate;
module.exports.lua_newtable = lapi.lua_newtable;
module.exports.lua_newthread = lstate.lua_newthread;
module.exports.lua_newuserdata = lapi.lua_newuserdata;
module.exports.lua_next = lapi.lua_next;
module.exports.lua_pcall = lapi.lua_pcall;
module.exports.lua_pcallk = lapi.lua_pcallk;
module.exports.lua_pop = lapi.lua_pop;
module.exports.lua_pushboolean = lapi.lua_pushboolean;
module.exports.lua_pushcclosure = lapi.lua_pushcclosure;
module.exports.lua_pushcfunction = lapi.lua_pushcfunction;
module.exports.lua_pushfstring = lapi.lua_pushfstring;
module.exports.lua_pushglobaltable = lapi.lua_pushglobaltable;
module.exports.lua_pushinteger = lapi.lua_pushinteger;
module.exports.lua_pushjsclosure = lapi.lua_pushjsclosure;
module.exports.lua_pushjsfunction = lapi.lua_pushjsfunction;
module.exports.lua_pushlightuserdata = lapi.lua_pushlightuserdata;
module.exports.lua_pushliteral = lapi.lua_pushliteral;
module.exports.lua_pushlstring = lapi.lua_pushlstring;
module.exports.lua_pushnil = lapi.lua_pushnil;
module.exports.lua_pushnumber = lapi.lua_pushnumber;
module.exports.lua_pushstring = lapi.lua_pushstring;
module.exports.lua_pushthread = lapi.lua_pushthread;
module.exports.lua_pushvalue = lapi.lua_pushvalue;
module.exports.lua_pushvfstring = lapi.lua_pushvfstring;
module.exports.lua_rawequal = lapi.lua_rawequal;
module.exports.lua_rawget = lapi.lua_rawget;
module.exports.lua_rawgeti = lapi.lua_rawgeti;
module.exports.lua_rawgetp = lapi.lua_rawgetp;
module.exports.lua_rawlen = lapi.lua_rawlen;
module.exports.lua_rawset = lapi.lua_rawset;
module.exports.lua_rawseti = lapi.lua_rawseti;
module.exports.lua_rawsetp = lapi.lua_rawsetp;
module.exports.lua_register = lapi.lua_register;
module.exports.lua_remove = lapi.lua_remove;
module.exports.lua_replace = lapi.lua_replace;
module.exports.lua_resume = ldo.lua_resume;
module.exports.lua_rotate = lapi.lua_rotate;
module.exports.lua_setallof = ldo.lua_setallof;
module.exports.lua_setfield = lapi.lua_setfield;
module.exports.lua_setglobal = lapi.lua_setglobal;
module.exports.lua_sethook = ldebug.lua_sethook;
module.exports.lua_seti = lapi.lua_seti;
module.exports.lua_setlocal = ldebug.lua_setlocal;
module.exports.lua_setmetatable = lapi.lua_setmetatable;
module.exports.lua_settable = lapi.lua_settable;
module.exports.lua_settop = lapi.lua_settop;
module.exports.lua_setupvalue = lapi.lua_setupvalue;
module.exports.lua_setuservalue = lapi.lua_setuservalue;
module.exports.lua_status = lapi.lua_status;
module.exports.lua_stringtonumber = lapi.lua_stringtonumber;
module.exports.lua_toboolean = lapi.lua_toboolean;
module.exports.lua_todataview = lapi.lua_todataview;
module.exports.lua_tointeger = lapi.lua_tointeger;
module.exports.lua_tointegerx = lapi.lua_tointegerx;
module.exports.lua_tojsstring = lapi.lua_tojsstring;
module.exports.lua_toljsstring = lapi.lua_toljsstring;
module.exports.lua_tolstring = lapi.lua_tolstring;
module.exports.lua_tonumber = lapi.lua_tonumber;
module.exports.lua_tonumberx = lapi.lua_tonumberx;
module.exports.lua_topointer = lapi.lua_topointer;
module.exports.lua_toproxy = lapi.lua_toproxy;
module.exports.lua_tostring = lapi.lua_tostring;
module.exports.lua_tothread = lapi.lua_tothread;
module.exports.lua_touserdata = lapi.lua_touserdata;
module.exports.lua_type = lapi.lua_type;
module.exports.lua_typename = lapi.lua_typename;
module.exports.lua_upvalueid = lapi.lua_upvalueid;
module.exports.lua_upvaluejoin = lapi.lua_upvaluejoin;
module.exports.lua_version = lapi.lua_version;
module.exports.lua_xmove = lapi.lua_xmove;
module.exports.lua_yield = ldo.lua_yield;
module.exports.lua_yieldk = ldo.lua_yieldk;
module.exports.lua_tocfunction = lapi.lua_tocfunction;
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const defs = __webpack_require__(2);
const lapi = __webpack_require__(38);
const ldebug = __webpack_require__(23);
const ldo = __webpack_require__(13);
const lstate = __webpack_require__(25);
module.exports.FENGARI_AUTHORS = defs.FENGARI_AUTHORS;
module.exports.FENGARI_COPYRIGHT = defs.FENGARI_COPYRIGHT;
module.exports.FENGARI_RELEASE = defs.FENGARI_RELEASE;
module.exports.FENGARI_VERSION = defs.FENGARI_VERSION;
module.exports.FENGARI_VERSION_MAJOR = defs.FENGARI_VERSION_MAJOR;
module.exports.FENGARI_VERSION_MINOR = defs.FENGARI_VERSION_MINOR;
module.exports.FENGARI_VERSION_NUM = defs.FENGARI_VERSION_NUM;
module.exports.FENGARI_VERSION_RELEASE = defs.FENGARI_VERSION_RELEASE;
module.exports.LUA_AUTHORS = defs.LUA_AUTHORS;
module.exports.LUA_COPYRIGHT = defs.LUA_COPYRIGHT;
module.exports.LUA_ERRERR = defs.thread_status.LUA_ERRERR;
module.exports.LUA_ERRGCMM = defs.thread_status.LUA_ERRGCMM;
module.exports.LUA_ERRMEM = defs.thread_status.LUA_ERRMEM;
module.exports.LUA_ERRRUN = defs.thread_status.LUA_ERRRUN;
module.exports.LUA_ERRSYNTAX = defs.thread_status.LUA_ERRSYNTAX;
module.exports.LUA_HOOKCALL = defs.LUA_HOOKCALL;
module.exports.LUA_HOOKCOUNT = defs.LUA_HOOKCOUNT;
module.exports.LUA_HOOKLINE = defs.LUA_HOOKLINE;
module.exports.LUA_HOOKRET = defs.LUA_HOOKRET;
module.exports.LUA_HOOKTAILCALL = defs.LUA_HOOKTAILCALL;
module.exports.LUA_INITVARVERSION = defs.LUA_INITVARVERSION;
module.exports.LUA_INIT_VAR = defs.LUA_INIT_VAR;
module.exports.LUA_MASKCALL = defs.LUA_MASKCALL;
module.exports.LUA_MASKCOUNT = defs.LUA_MASKCOUNT;
module.exports.LUA_MASKLINE = defs.LUA_MASKLINE;
module.exports.LUA_MASKRET = defs.LUA_MASKRET;
module.exports.LUA_MINSTACK = defs.LUA_MINSTACK;
module.exports.LUA_MULTRET = defs.LUA_MULTRET;
module.exports.LUA_NUMTAGS = defs.LUA_NUMTAGS;
module.exports.LUA_OK = defs.thread_status.LUA_OK;
module.exports.LUA_OPADD = defs.LUA_OPADD;
module.exports.LUA_OPBAND = defs.LUA_OPBAND;
module.exports.LUA_OPBNOT = defs.LUA_OPBNOT;
module.exports.LUA_OPBOR = defs.LUA_OPBOR;
module.exports.LUA_OPBXOR = defs.LUA_OPBXOR;
module.exports.LUA_OPDIV = defs.LUA_OPDIV;
module.exports.LUA_OPEQ = defs.LUA_OPEQ;
module.exports.LUA_OPIDIV = defs.LUA_OPIDIV;
module.exports.LUA_OPLE = defs.LUA_OPLE;
module.exports.LUA_OPLT = defs.LUA_OPLT;
module.exports.LUA_OPMOD = defs.LUA_OPMOD;
module.exports.LUA_OPMUL = defs.LUA_OPMUL;
module.exports.LUA_OPPOW = defs.LUA_OPPOW;
module.exports.LUA_OPSHL = defs.LUA_OPSHL;
module.exports.LUA_OPSHR = defs.LUA_OPSHR;
module.exports.LUA_OPSUB = defs.LUA_OPSUB;
module.exports.LUA_OPUNM = defs.LUA_OPUNM;
module.exports.LUA_REGISTRYINDEX = defs.LUA_REGISTRYINDEX;
module.exports.LUA_RELEASE = defs.LUA_RELEASE;
module.exports.LUA_RIDX_GLOBALS = defs.LUA_RIDX_GLOBALS;
module.exports.LUA_RIDX_LAST = defs.LUA_RIDX_LAST;
module.exports.LUA_RIDX_MAINTHREAD = defs.LUA_RIDX_MAINTHREAD;
module.exports.LUA_SIGNATURE = defs.LUA_SIGNATURE;
module.exports.LUA_TNONE = defs.CT.LUA_TNONE;
module.exports.LUA_TNIL = defs.CT.LUA_TNIL;
module.exports.LUA_TBOOLEAN = defs.CT.LUA_TBOOLEAN;
module.exports.LUA_TLIGHTUSERDATA = defs.CT.LUA_TLIGHTUSERDATA;
module.exports.LUA_TNUMBER = defs.CT.LUA_TNUMBER;
module.exports.LUA_TSTRING = defs.CT.LUA_TSTRING;
module.exports.LUA_TTABLE = defs.CT.LUA_TTABLE;
module.exports.LUA_TFUNCTION = defs.CT.LUA_TFUNCTION;
module.exports.LUA_TUSERDATA = defs.CT.LUA_TUSERDATA;
module.exports.LUA_TTHREAD = defs.CT.LUA_TTHREAD;
module.exports.LUA_VERSION = defs.LUA_VERSION;
module.exports.LUA_VERSION_MAJOR = defs.LUA_VERSION_MAJOR;
module.exports.LUA_VERSION_MINOR = defs.LUA_VERSION_MINOR;
module.exports.LUA_VERSION_NUM = defs.LUA_VERSION_NUM;
module.exports.LUA_VERSION_RELEASE = defs.LUA_VERSION_RELEASE;
module.exports.LUA_VERSUFFIX = defs.LUA_VERSUFFIX;
module.exports.LUA_YIELD = defs.thread_status.LUA_YIELD;
module.exports.lua_Debug = defs.lua_Debug;
module.exports.lua_upvalueindex = defs.lua_upvalueindex;
module.exports.to_jsstring = defs.to_jsstring;
module.exports.to_luastring = defs.to_luastring;
module.exports.LUA_CDIR = defs.LUA_CDIR;
module.exports.LUA_CPATH_DEFAULT = defs.LUA_CPATH_DEFAULT;
module.exports.LUA_EXEC_DIR = defs.LUA_EXEC_DIR;
module.exports.LUA_LDIR = defs.LUA_LDIR;
module.exports.LUA_PATH_DEFAULT = defs.LUA_PATH_DEFAULT;
module.exports.LUA_PATH_MARK = defs.LUA_PATH_MARK;
module.exports.LUA_PATH_SEP = defs.LUA_PATH_SEP;
module.exports.LUA_ROOT = defs.LUA_ROOT;
module.exports.LUA_SHRDIR = defs.LUA_SHRDIR;
module.exports.LUA_VDIR = defs.LUA_VDIR;
module.exports.LUA_DIRSEP = defs.LUA_DIRSEP;
module.exports.lua_absindex = lapi.lua_absindex;
module.exports.lua_arith = lapi.lua_arith;
module.exports.lua_atpanic = lapi.lua_atpanic;
module.exports.lua_atnativeerror = lapi.lua_atnativeerror;
module.exports.lua_call = lapi.lua_call;
module.exports.lua_callk = lapi.lua_callk;
module.exports.lua_checkstack = lapi.lua_checkstack;
module.exports.lua_close = lstate.lua_close;
module.exports.lua_compare = lapi.lua_compare;
module.exports.lua_concat = lapi.lua_concat;
module.exports.lua_copy = lapi.lua_copy;
module.exports.lua_createtable = lapi.lua_createtable;
module.exports.lua_dump = lapi.lua_dump;
module.exports.lua_error = lapi.lua_error;
module.exports.lua_gc = lapi.lua_gc;
module.exports.lua_getallocf = lapi.lua_getallocf;
module.exports.lua_getextraspace = lapi.lua_getextraspace;
module.exports.lua_getfield = lapi.lua_getfield;
module.exports.lua_getglobal = lapi.lua_getglobal;
module.exports.lua_gethook = ldebug.lua_gethook;
module.exports.lua_gethookcount = ldebug.lua_gethookcount;
module.exports.lua_gethookmask = ldebug.lua_gethookmask;
module.exports.lua_geti = lapi.lua_geti;
module.exports.lua_getinfo = ldebug.lua_getinfo;
module.exports.lua_getlocal = ldebug.lua_getlocal;
module.exports.lua_getmetatable = lapi.lua_getmetatable;
module.exports.lua_getstack = ldebug.lua_getstack;
module.exports.lua_gettable = lapi.lua_gettable;
module.exports.lua_gettop = lapi.lua_gettop;
module.exports.lua_getupvalue = lapi.lua_getupvalue;
module.exports.lua_getuservalue = lapi.lua_getuservalue;
module.exports.lua_insert = lapi.lua_insert;
module.exports.lua_isboolean = lapi.lua_isboolean;
module.exports.lua_iscfunction = lapi.lua_iscfunction;
module.exports.lua_isfunction = lapi.lua_isfunction;
module.exports.lua_isinteger = lapi.lua_isinteger;
module.exports.lua_islightuserdata = lapi.lua_islightuserdata;
module.exports.lua_isnil = lapi.lua_isnil;
module.exports.lua_isnone = lapi.lua_isnone;
module.exports.lua_isnoneornil = lapi.lua_isnoneornil;
module.exports.lua_isnumber = lapi.lua_isnumber;
module.exports.lua_isproxy = lapi.lua_isproxy;
module.exports.lua_isstring = lapi.lua_isstring;
module.exports.lua_istable = lapi.lua_istable;
module.exports.lua_isthread = lapi.lua_isthread;
module.exports.lua_isuserdata = lapi.lua_isuserdata;
module.exports.lua_isyieldable = ldo.lua_isyieldable;
module.exports.lua_len = lapi.lua_len;
module.exports.lua_load = lapi.lua_load;
module.exports.lua_newstate = lstate.lua_newstate;
module.exports.lua_newtable = lapi.lua_newtable;
module.exports.lua_newthread = lstate.lua_newthread;
module.exports.lua_newuserdata = lapi.lua_newuserdata;
module.exports.lua_next = lapi.lua_next;
module.exports.lua_pcall = lapi.lua_pcall;
module.exports.lua_pcallk = lapi.lua_pcallk;
module.exports.lua_pop = lapi.lua_pop;
module.exports.lua_pushboolean = lapi.lua_pushboolean;
module.exports.lua_pushcclosure = lapi.lua_pushcclosure;
module.exports.lua_pushcfunction = lapi.lua_pushcfunction;
module.exports.lua_pushfstring = lapi.lua_pushfstring;
module.exports.lua_pushglobaltable = lapi.lua_pushglobaltable;
module.exports.lua_pushinteger = lapi.lua_pushinteger;
module.exports.lua_pushjsclosure = lapi.lua_pushjsclosure;
module.exports.lua_pushjsfunction = lapi.lua_pushjsfunction;
module.exports.lua_pushlightuserdata = lapi.lua_pushlightuserdata;
module.exports.lua_pushliteral = lapi.lua_pushliteral;
module.exports.lua_pushlstring = lapi.lua_pushlstring;
module.exports.lua_pushnil = lapi.lua_pushnil;
module.exports.lua_pushnumber = lapi.lua_pushnumber;
module.exports.lua_pushstring = lapi.lua_pushstring;
module.exports.lua_pushthread = lapi.lua_pushthread;
module.exports.lua_pushvalue = lapi.lua_pushvalue;
module.exports.lua_pushvfstring = lapi.lua_pushvfstring;
module.exports.lua_rawequal = lapi.lua_rawequal;
module.exports.lua_rawget = lapi.lua_rawget;
module.exports.lua_rawgeti = lapi.lua_rawgeti;
module.exports.lua_rawgetp = lapi.lua_rawgetp;
module.exports.lua_rawlen = lapi.lua_rawlen;
module.exports.lua_rawset = lapi.lua_rawset;
module.exports.lua_rawseti = lapi.lua_rawseti;
module.exports.lua_rawsetp = lapi.lua_rawsetp;
module.exports.lua_register = lapi.lua_register;
module.exports.lua_remove = lapi.lua_remove;
module.exports.lua_replace = lapi.lua_replace;
module.exports.lua_resume = ldo.lua_resume;
module.exports.lua_rotate = lapi.lua_rotate;
module.exports.lua_setallof = ldo.lua_setallof;
module.exports.lua_setfield = lapi.lua_setfield;
module.exports.lua_setglobal = lapi.lua_setglobal;
module.exports.lua_sethook = ldebug.lua_sethook;
module.exports.lua_seti = lapi.lua_seti;
module.exports.lua_setlocal = ldebug.lua_setlocal;
module.exports.lua_setmetatable = lapi.lua_setmetatable;
module.exports.lua_settable = lapi.lua_settable;
module.exports.lua_settop = lapi.lua_settop;
module.exports.lua_setupvalue = lapi.lua_setupvalue;
module.exports.lua_setuservalue = lapi.lua_setuservalue;
module.exports.lua_status = lapi.lua_status;
module.exports.lua_stringtonumber = lapi.lua_stringtonumber;
module.exports.lua_toboolean = lapi.lua_toboolean;
module.exports.lua_todataview = lapi.lua_todataview;
module.exports.lua_tointeger = lapi.lua_tointeger;
module.exports.lua_tointegerx = lapi.lua_tointegerx;
module.exports.lua_tojsstring = lapi.lua_tojsstring;
module.exports.lua_toljsstring = lapi.lua_toljsstring;
module.exports.lua_tolstring = lapi.lua_tolstring;
module.exports.lua_tonumber = lapi.lua_tonumber;
module.exports.lua_tonumberx = lapi.lua_tonumberx;
module.exports.lua_topointer = lapi.lua_topointer;
module.exports.lua_toproxy = lapi.lua_toproxy;
module.exports.lua_tostring = lapi.lua_tostring;
module.exports.lua_tothread = lapi.lua_tothread;
module.exports.lua_touserdata = lapi.lua_touserdata;
module.exports.lua_type = lapi.lua_type;
module.exports.lua_typename = lapi.lua_typename;
module.exports.lua_upvalueid = lapi.lua_upvalueid;
module.exports.lua_upvaluejoin = lapi.lua_upvaluejoin;
module.exports.lua_version = lapi.lua_version;
module.exports.lua_xmove = lapi.lua_xmove;
module.exports.lua_yield = ldo.lua_yield;
module.exports.lua_yieldk = ldo.lua_yieldk;
module.exports.lua_tocfunction = lapi.lua_tocfunction;
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const ljstype = __webpack_require__(40);
const ldebug = __webpack_require__(19);
const ldo = __webpack_require__(12);
const lfunc = __webpack_require__(20);
const lstate = __webpack_require__(21);
const lstring = __webpack_require__(15);
const ltable = __webpack_require__(14);
const luaconf = __webpack_require__(18);
const lvm = __webpack_require__(27);
const llimit = __webpack_require__(8);
const ltm = __webpack_require__(26);
const CT = defs.constant_types;
const char = defs.char;
const LUA_TPROTO = CT.LUA_NUMTAGS;
const LUA_TDEADKEY = CT.LUA_NUMTAGS+1;
class TValue {
constructor(type, value) {
this.type = type;
this.value = value;
}
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
ttype() {
return this.type & 0x3F;
}
/* type tag of a TValue with no variants (bits 0-3) */
ttnov() {
return this.type & 0x0F;
}
checktag(t) {
return this.type === t;
}
checktype(t) {
return this.ttnov() === t;
}
ttisnumber() {
return this.checktype(CT.LUA_TNUMBER);
}
ttisfloat() {
return this.checktag(CT.LUA_TNUMFLT);
}
ttisinteger() {
return this.checktag(CT.LUA_TNUMINT);
}
ttisnil() {
return this.checktag(CT.LUA_TNIL);
}
ttisboolean() {
return this.checktag(CT.LUA_TBOOLEAN);
}
ttislightuserdata() {
return this.checktag(CT.LUA_TLIGHTUSERDATA);
}
ttisstring() {
return this.checktype(CT.LUA_TSTRING);
}
ttisshrstring() {
return this.checktag(CT.LUA_TSHRSTR);
}
ttislngstring() {
return this.checktag(CT.LUA_TLNGSTR);
}
ttistable() {
return this.checktag(CT.LUA_TTABLE);
}
ttisfunction() {
return this.checktype(CT.LUA_TFUNCTION);
}
ttisclosure() {
return (this.type & 0x1F) === CT.LUA_TFUNCTION;
}
ttisCclosure() {
return this.checktag(CT.LUA_TCCL);
}
ttisLclosure() {
return this.checktag(CT.LUA_TLCL);
}
ttislcf() {
return this.checktag(CT.LUA_TLCF);
}
ttisfulluserdata() {
return this.checktag(CT.LUA_TUSERDATA);
}
ttisthread() {
return this.checktag(CT.LUA_TTHREAD);
}
ttisdeadkey() {
return this.checktag(LUA_TDEADKEY);
}
l_isfalse() {
return this.ttisnil() || (this.ttisboolean() && this.value === false);
}
setfltvalue(x) {
this.type = CT.LUA_TNUMFLT;
this.value = x;
}
chgfltvalue(x) {
assert(this.type == CT.LUA_TNUMFLT);
this.value = x;
}
setivalue(x) {
this.type = CT.LUA_TNUMINT;
this.value = x;
}
chgivalue(x) {
assert(this.type == CT.LUA_TNUMINT);
this.value = x;
}
setnilvalue() {
this.type = CT.LUA_TNIL;
this.value = void 0;
}
setfvalue(x) {
this.type = CT.LUA_TLCF;
this.value = x;
}
setpvalue(x) {
this.type = CT.LUA_TLIGHTUSERDATA;
this.value = x;
}
setbvalue(x) {
this.type = CT.LUA_TBOOLEAN;
this.value = x;
}
setsvalue(x) {
this.type = CT.LUA_TLNGSTR; /* LUA_TSHRSTR? */
this.value = x;
}
setuvalue(x) {
this.type = CT.LUA_TUSERDATA;
this.value = x;
}
setthvalue(x) {
this.type = CT.LUA_TTHREAD;
this.value = x;
}
setclLvalue(x) {
this.type = CT.LUA_TLCL;
this.value = x;
}
setclCvalue(x) {
this.type = CT.LUA_TCCL;
this.value = x;
}
sethvalue(x) {
this.type = CT.LUA_TTABLE;
this.value = x;
}
setdeadvalue() {
this.type = LUA_TDEADKEY;
this.value = null;
}
setfrom(tv) { /* in lua C source setobj2t is often used for this */
this.type = tv.type;
this.value = tv.value;
}
tsvalue() {
assert(this.ttisstring());
return this.value;
}
svalue() {
return this.tsvalue().getstr();
}
vslen() {
return this.tsvalue().tsslen();
}
jsstring(from, to) {
return defs.to_jsstring(this.svalue(), from, to);
}
}
const pushobj2s = function(L, tv) {
L.stack[L.top++] = new TValue(tv.type, tv.value);
};
const pushsvalue2s = function(L, ts) {
L.stack[L.top++] = new TValue(CT.LUA_TLNGSTR, ts);
};
/* from stack to (same) stack */
const setobjs2s = function(L, newidx, oldidx) {
L.stack[newidx].setfrom(L.stack[oldidx]);
};
/* to stack (not from same stack) */
const setobj2s = function(L, newidx, oldtv) {
L.stack[newidx].setfrom(oldtv);
};
const setsvalue2s = function(L, newidx, ts) {
L.stack[newidx].setsvalue(ts);
};
const luaO_nilobject = new TValue(CT.LUA_TNIL, null);
Object.freeze(luaO_nilobject);
module.exports.luaO_nilobject = luaO_nilobject;
class LClosure {
constructor(L, n) {
this.id = L.l_G.id_counter++;
this.p = null;
this.nupvalues = n;
this.upvals = new Array(n); /* list of upvalues as UpVals. initialised in luaF_initupvals */
}
}
class CClosure {
constructor(L, f, n) {
this.id = L.l_G.id_counter++;
this.f = f;
this.nupvalues = n;
this.upvalue = new Array(n); /* list of upvalues as TValues */
while (n--) {
this.upvalue[n] = new TValue(CT.LUA_TNIL, null);
}
}
}
class Udata {
constructor(L, size) {
this.id = L.l_G.id_counter++;
this.metatable = null;
this.uservalue = new TValue(CT.LUA_TNIL, null);
this.len = size;
this.data = Object.create(null); // ignores size argument
}
}
/*
** Description of a local variable for function prototypes
** (used for debug information)
*/
class LocVar {
constructor() {
this.varname = null;
this.startpc = NaN; /* first point where variable is active */
this.endpc = NaN; /* first point where variable is dead */
}
}
const RETS = defs.to_luastring("...", true);
const PRE = defs.to_luastring("[string \"");
const POS = defs.to_luastring("\"]");
const luaO_chunkid = function(source, bufflen) {
let l = source.length;
let out;
if (source[0] === char['=']) { /* 'literal' source */
if (l < bufflen) /* small enough? */
out = source.slice(1);
else { /* truncate it */
out = source.slice(1, bufflen);
}
} else if (source[0] === char['@']) { /* file name */
if (l <= bufflen) /* small enough? */
out = source.slice(1);
else { /* add '...' before rest of name */
bufflen -= RETS.length;
out = RETS.concat(source.slice(1 + l - bufflen));
}
} else { /* string; format as [string "source"] */
let nli = source.indexOf(char['\n']); /* find first new line (if any) */
out = PRE; /* add prefix */
bufflen -= PRE.length + RETS.length + POS.length + 1; /* save space for prefix+suffix+'\0' */
if (l < bufflen && nli === -1) { /* small one-line source? */
out = out.concat(source, POS); /* keep it */
} else {
if (nli !== -1) l = nli; /* stop at first newline */
if (l > bufflen) l = bufflen;
out = out.concat(source.slice(0, l), RETS, POS);
}
}
return out;
};
const luaO_hexavalue = function(c) {
if (ljstype.lisdigit(c)) return c - char['0'];
else return (String.fromCharCode(c).toLowerCase().charCodeAt(0) - char['a']) + 10;
};
const UTF8BUFFSZ = 8;
const luaO_utf8desc = function(buff, x) {
let n = 1; /* number of bytes put in buffer (backwards) */
assert(x <= 0x10FFFF);
if (x < 0x80) /* ascii? */
buff[UTF8BUFFSZ - 1] = x;
else { /* need continuation bytes */
let mfb = 0x3f; /* maximum that fits in first byte */
do {
buff[UTF8BUFFSZ - (n++)] = 0x80 | (x & 0x3f);
x >>= 6; /* remove added bits */
mfb >>= 1; /* now there is one less bit available in first byte */
} while (x > mfb); /* still needs continuation byte? */
buff[UTF8BUFFSZ - n] = (~mfb << 1) | x; /* add first byte */
}
return n;
};
/* maximum number of significant digits to read (to avoid overflows
even with single floats) */
const MAXSIGDIG = 30;
/*
** convert an hexadecimal numeric string to a number, following
** C99 specification for 'strtod'
*/
const lua_strx2number = function(s) {
let i = 0;
let dot = char[luaconf.lua_getlocaledecpoint()];
let r = 0.0; /* result (accumulator) */
let sigdig = 0; /* number of significant digits */
let nosigdig = 0; /* number of non-significant digits */
let e = 0; /* exponent correction */
let neg; /* 1 if number is negative */
let hasdot = false; /* true after seen a dot */
while (ljstype.lisspace(s[i])) i++; /* skip initial spaces */
if ((neg = (s[i] === char['-']))) i++; /* check signal */
else if (s[i] === char['+']) i++;
if (!(s[i] === char['0'] && (s[i+1] === char['x'] || s[i+1] === char['X']))) /* check '0x' */
return null; /* invalid format (no '0x') */
for (i += 2; ; i++) { /* skip '0x' and read numeral */
if (s[i] === dot) {
if (hasdot) break; /* second dot? stop loop */
else hasdot = true;
} else if (ljstype.lisxdigit(s[i])) {
if (sigdig === 0 && s[i] === char['0']) /* non-significant digit (zero)? */
nosigdig++;
else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
r = (r * 16) + luaO_hexavalue(s[i]);
else e++; /* too many digits; ignore, but still count for exponent */
if (hasdot) e--; /* decimal digit? correct exponent */
} else break; /* neither a dot nor a digit */
}
if (nosigdig + sigdig === 0) /* no digits? */
return null; /* invalid format */
e *= 4; /* each digit multiplies/divides value by 2^4 */
if (s[i] === char['p'] || s[i] === char['P']) { /* exponent part? */
let exp1 = 0; /* exponent value */
let neg1; /* exponent signal */
i++; /* skip 'p' */
if ((neg1 = (s[i] === char['-']))) i++; /* signal */
else if (s[i] === char['+']) i++;
if (!ljstype.lisdigit(s[i]))
return null; /* invalid; must have at least one digit */
while (ljstype.lisdigit(s[i])) /* read exponent */
exp1 = exp1 * 10 + s[i++] - char['0'];
if (neg1) exp1 = -exp1;
e += exp1;
}
if (neg) r = -r;
while (ljstype.lisspace(s[i])) i++; /* skip trailing spaces */
return i === s.length ? luaconf.ldexp(r, e) : null; /* Only valid if nothing left is s*/
};
const lua_str2number = function(s) {
/* parseFloat ignores trailing junk, validate with regex first */
let str = defs.to_jsstring(s);
if (!/^[\t\v\f \n\r]*[\+\-]?([0-9]+\.?[0-9]*|\.[0-9]*)([eE][\+\-]?[0-9]+)?[\t\v\f \n\r]*$/.test(str))
return null;
let flt = parseFloat(str);
return !isNaN(flt) ? flt : null;
};
const l_str2dloc = function(s, mode) {
return mode === 'x' ? lua_strx2number(s) : lua_str2number(s);
};
const l_str2d = function(s) {
let pidx = /[.xXnN]/g.exec(String.fromCharCode(...s));
pidx = pidx ? pidx.index : null;
let pmode = pidx ? s[pidx] : null;
let mode = pmode ? String.fromCharCode(pmode).toLowerCase() : 0;
if (mode === 'n') /* reject 'inf' and 'nan' */
return null;
let end = l_str2dloc(s, mode); /* try to convert */
if (end === null) { /* failed? may be a different locale */
// throw new Error("Locale not available to handle number"); // TODO
}
return end;
};
const MAXBY10 = Math.floor(llimit.MAX_INT / 10);
const MAXLASTD = llimit.MAX_INT % 10;
const l_str2int = function(s) {
let i = 0;
let a = 0;
let empty = true;
let neg;
while (ljstype.lisspace(s[i])) i++; /* skip initial spaces */
if ((neg = (s[i] === char['-']))) i++;
else if (s[i] === char['+']) i++;
if (s[i] === char['0'] && (s[i+1] === char['x'] || s[i+1] === char['X'])) { /* hex? */
i += 2; /* skip '0x' */
for (; ljstype.lisxdigit(s[i]); i++) {
a = (a * 16 + luaO_hexavalue(s[i]))|0;
empty = false;
}
} else { /* decimal */
for (; ljstype.lisdigit(s[i]); i++) {
let d = s[i] - char['0'];
if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */
return null; /* do not accept it (as integer) */
a = (a * 10 + d)|0;
empty = false;
}
}
while (ljstype.lisspace(s[i])) i++; /* skip trailing spaces */
if (empty || (i !== s.length)) return null; /* something wrong in the numeral */
else {
return (neg ? -a : a)|0;
}
};
const luaO_str2num = function(s) {
let s2i = l_str2int(s);
if (s2i !== null) { /* try as an integer */
return new TValue(CT.LUA_TNUMINT, s2i);
} else { /* else try as a float */
s2i = l_str2d(s);
if (s2i !== null) {
return new TValue(CT.LUA_TNUMFLT, s2i);
} else
return false; /* conversion failed */
}
};
const luaO_utf8esc = function(x) {
let buff = [];
let n = 1; /* number of bytes put in buffer (backwards) */
assert(x <= 0x10ffff);
if (x < 0x80) /* ascii? */
buff[UTF8BUFFSZ - 1] = x;
else { /* need continuation bytes */
let mfb = 0x3f; /* maximum that fits in first byte */
do { /* add continuation bytes */
buff[UTF8BUFFSZ - (n++)] = 0x80 | (x & 0x3f);
x >>= 6; /* remove added bits */
mfb >>= 1; /* now there is one less bit available in first byte */
} while (x > mfb); /* still needs continuation byte? */
buff[UTF8BUFFSZ - n] = (~mfb << 1) | x; /* add first byte */
}
return {
buff: buff,
n: n
};
};
/* this currently returns new TValue instead of modifying */
const luaO_tostring = function(L, obj) {
let buff;
if (obj.ttisinteger())
buff = defs.to_luastring(luaconf.lua_integer2str(obj.value));
else {
let str = luaconf.lua_number2str(obj.value);
buff = defs.to_luastring(str);
// Assume no LUA_COMPAT_FLOATSTRING
if (/^[-0123456789]+$/.test(str)) { /* looks like an int? */
buff.push(char[luaconf.lua_getlocaledecpoint()]);
buff.push(char['0']); /* adds '.0' to result */
}
}
obj.setsvalue(lstring.luaS_bless(L, buff));
};
const pushstr = function(L, str) {
ldo.luaD_inctop(L);
setsvalue2s(L, L.top-1, lstring.luaS_new(L, str));
};
const luaO_pushvfstring = function(L, fmt, argp) {
let n = 0;
let i = 0;
let a = 0;
let e;
while (1) {
e = fmt.indexOf(char['%'], i);
if (e == -1) break;
pushstr(L, fmt.slice(i, e));
switch(fmt[e+1]) {
case char['s']:
let s = argp[a++];
if (s === null) s = defs.to_luastring("(null)", true);
pushstr(L, s);
break;
case char['c']:
let buff = argp[a++];
if (ljstype.lisprint(buff))
pushstr(L, [buff]);
else
luaO_pushfstring(L, defs.to_luastring("<\\%d>", true), buff);
break;
case char['d']:
case char['I']:
ldo.luaD_inctop(L);
L.stack[L.top-1].setivalue(argp[a++]);
luaO_tostring(L, L.stack[L.top-1]);
break;
case char['f']:
ldo.luaD_inctop(L);
L.stack[L.top-1].setfltvalue(argp[a++]);
luaO_tostring(L, L.stack[L.top-1]);
break;
case char['p']:
let v = argp[a++];
if (v instanceof lstate.lua_State ||
v instanceof ltable.Table ||
v instanceof Udata ||
v instanceof LClosure ||
v instanceof CClosure ||
v instanceof lfunc.UpVal) {
pushstr(L, defs.to_luastring("0x"+v.id.toString(16)));
} else {
/* user provided object. no id available */
pushstr(L, defs.to_luastring("<id NYI>"));
}
break;
case char['U']:
pushstr(L, defs.to_luastring(String.fromCodePoint(argp[a++])));
break;
case char['%']:
pushstr(L, [char['%']]);
break;
default: {
ldebug.luaG_runerror(L, defs.to_luastring("invalid option '%%%c' to 'lua_pushfstring'"), fmt[e + 1]);
}
}
n += 2;
i = e + 2;
}
ldo.luaD_checkstack(L, 1);
pushstr(L, fmt.slice(i));
if (n > 0) lvm.luaV_concat(L, n+1);
return L.stack[L.top-1].svalue();
};
const luaO_pushfstring = function(L, fmt, ...argp) {
return luaO_pushvfstring(L, fmt, argp);
};
/*
** converts an integer to a "floating point byte", represented as
** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
** eeeee !== 0 and (xxx) otherwise.
*/
const luaO_int2fb = function(x) {
let e = 0; /* exponent */
if (x < 8) return x;
while (x >= (8 << 4)) { /* coarse steps */
x = (x + 0xf) >> 4; /* x = ceil(x / 16) */
e += 4;
}
while (x >= (8 << 1)) { /* fine steps */
x = (x + 1) >> 1; /* x = ceil(x / 2) */
e++;
}
return ((e+1) << 3) | (x - 8);
};
const intarith = function(L, op, v1, v2) {
switch (op) {
case defs.LUA_OPADD: return (v1 + v2)|0;
case defs.LUA_OPSUB: return (v1 - v2)|0;
case defs.LUA_OPMUL: return Math.imul(v1, v2);
case defs.LUA_OPMOD: return lvm.luaV_mod(L, v1, v2);
case defs.LUA_OPIDIV: return lvm.luaV_div(L, v1, v2);
case defs.LUA_OPBAND: return (v1 & v2);
case defs.LUA_OPBOR: return (v1 | v2);
case defs.LUA_OPBXOR: return (v1 ^ v2);
case defs.LUA_OPSHL: return lvm.luaV_shiftl(v1, v2);
case defs.LUA_OPSHR: return lvm.luaV_shiftl(v1, -v2);
case defs.LUA_OPUNM: return (0 - v1)|0;
case defs.LUA_OPBNOT: return (~0 ^ v1);
default: assert(0);
}
};
const numarith = function(L, op, v1, v2) {
switch (op) {
case defs.LUA_OPADD: return v1 + v2;
case defs.LUA_OPSUB: return v1 - v2;
case defs.LUA_OPMUL: return v1 * v2;
case defs.LUA_OPDIV: return v1 / v2;
case defs.LUA_OPPOW: return Math.pow(v1, v2);
case defs.LUA_OPIDIV: return Math.floor(v1 / v2);
case defs.LUA_OPUNM: return -v1;
case defs.LUA_OPMOD: return llimit.luai_nummod(L, v1, v2);
default: assert(0);
}
};
const luaO_arith = function(L, op, p1, p2, p3) {
let res = (typeof p3 === "number") ? L.stack[p3] : p3; /* FIXME */
switch (op) {
case defs.LUA_OPBAND: case defs.LUA_OPBOR: case defs.LUA_OPBXOR:
case defs.LUA_OPSHL: case defs.LUA_OPSHR:
case defs.LUA_OPBNOT: { /* operate only on integers */
let i1, i2;
if ((i1 = lvm.tointeger(p1)) !== false && (i2 = lvm.tointeger(p2)) !== false) {
res.setivalue(intarith(L, op, i1, i2));
return;
}
else break; /* go to the end */
}
case defs.LUA_OPDIV: case defs.LUA_OPPOW: { /* operate only on floats */
let n1, n2;
if ((n1 = lvm.tonumber(p1)) !== false && (n2 = lvm.tonumber(p2)) !== false) {
res.setfltvalue(numarith(L, op, n1, n2));
return;
}
else break; /* go to the end */
}
default: { /* other operations */
let n1, n2;
if (p1.ttisinteger() && p2.ttisinteger()) {
res.setivalue(intarith(L, op, p1.value, p2.value));
return;
}
else if ((n1 = lvm.tonumber(p1)) !== false && (n2 = lvm.tonumber(p2)) !== false) {
res.setfltvalue(numarith(L, op, n1, n2));
return;
}
else break; /* go to the end */
}
}
/* could not perform raw operation; try metamethod */
assert(L !== null); /* should not fail when folding (compile time) */
ltm.luaT_trybinTM(L, p1, p2, p3, (op - defs.LUA_OPADD) + ltm.TMS.TM_ADD);
};
module.exports.CClosure = CClosure;
module.exports.LClosure = LClosure;
module.exports.LUA_TDEADKEY = LUA_TDEADKEY;
module.exports.LUA_TPROTO = LUA_TPROTO;
module.exports.LocVar = LocVar;
module.exports.TValue = TValue;
module.exports.Udata = Udata;
module.exports.UTF8BUFFSZ = UTF8BUFFSZ;
module.exports.luaO_arith = luaO_arith;
module.exports.luaO_chunkid = luaO_chunkid;
module.exports.luaO_hexavalue = luaO_hexavalue;
module.exports.luaO_int2fb = luaO_int2fb;
module.exports.luaO_pushfstring = luaO_pushfstring;
module.exports.luaO_pushvfstring = luaO_pushvfstring;
module.exports.luaO_str2num = luaO_str2num;
module.exports.luaO_tostring = luaO_tostring;
module.exports.luaO_utf8desc = luaO_utf8desc;
module.exports.luaO_utf8esc = luaO_utf8esc;
module.exports.numarith = numarith;
module.exports.pushobj2s = pushobj2s;
module.exports.pushsvalue2s = pushsvalue2s;
module.exports.setobjs2s = setobjs2s;
module.exports.setobj2s = setobj2s;
module.exports.setsvalue2s = setsvalue2s;
/***/ }),
/* 6 */
/***/ (function(module, exports) {
module.exports = function() {
throw new Error("define cannot be used indirect");
};
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const ljstype = __webpack_require__(54);
const ldebug = __webpack_require__(23);
const ldo = __webpack_require__(13);
const lfunc = __webpack_require__(24);
const lstate = __webpack_require__(25);
const lstring = __webpack_require__(17);
const ltable = __webpack_require__(16);
const luaconf = __webpack_require__(22);
const lvm = __webpack_require__(32);
const llimit = __webpack_require__(10);
const ltm = __webpack_require__(31);
const CT = defs.constant_types;
const char = defs.char;
const LUA_TPROTO = CT.LUA_NUMTAGS;
const LUA_TDEADKEY = CT.LUA_NUMTAGS+1;
class TValue {
constructor(type, value) {
this.type = type;
this.value = value;
}
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
ttype() {
return this.type & 0x3F;
}
/* type tag of a TValue with no variants (bits 0-3) */
ttnov() {
return this.type & 0x0F;
}
checktag(t) {
return this.type === t;
}
checktype(t) {
return this.ttnov() === t;
}
ttisnumber() {
return this.checktype(CT.LUA_TNUMBER);
}
ttisfloat() {
return this.checktag(CT.LUA_TNUMFLT);
}
ttisinteger() {
return this.checktag(CT.LUA_TNUMINT);
}
ttisnil() {
return this.checktag(CT.LUA_TNIL);
}
ttisboolean() {
return this.checktag(CT.LUA_TBOOLEAN);
}
ttislightuserdata() {
return this.checktag(CT.LUA_TLIGHTUSERDATA);
}
ttisstring() {
return this.checktype(CT.LUA_TSTRING);
}
ttisshrstring() {
return this.checktag(CT.LUA_TSHRSTR);
}
ttislngstring() {
return this.checktag(CT.LUA_TLNGSTR);
}
ttistable() {
return this.checktag(CT.LUA_TTABLE);
}
ttisfunction() {
return this.checktype(CT.LUA_TFUNCTION);
}
ttisclosure() {
return (this.type & 0x1F) === CT.LUA_TFUNCTION;
}
ttisCclosure() {
return this.checktag(CT.LUA_TCCL);
}
ttisLclosure() {
return this.checktag(CT.LUA_TLCL);
}
ttislcf() {
return this.checktag(CT.LUA_TLCF);
}
ttisfulluserdata() {
return this.checktag(CT.LUA_TUSERDATA);
}
ttisthread() {
return this.checktag(CT.LUA_TTHREAD);
}
ttisdeadkey() {
return this.checktag(LUA_TDEADKEY);
}
l_isfalse() {
return this.ttisnil() || (this.ttisboolean() && this.value === false);
}
setfltvalue(x) {
this.type = CT.LUA_TNUMFLT;
this.value = x;
}
chgfltvalue(x) {
assert(this.type == CT.LUA_TNUMFLT);
this.value = x;
}
setivalue(x) {
this.type = CT.LUA_TNUMINT;
this.value = x;
}
chgivalue(x) {
assert(this.type == CT.LUA_TNUMINT);
this.value = x;
}
setnilvalue() {
this.type = CT.LUA_TNIL;
this.value = void 0;
}
setfvalue(x) {
this.type = CT.LUA_TLCF;
this.value = x;
}
setpvalue(x) {
this.type = CT.LUA_TLIGHTUSERDATA;
this.value = x;
}
setbvalue(x) {
this.type = CT.LUA_TBOOLEAN;
this.value = x;
}
setsvalue(x) {
this.type = CT.LUA_TLNGSTR; /* LUA_TSHRSTR? */
this.value = x;
}
setuvalue(x) {
this.type = CT.LUA_TUSERDATA;
this.value = x;
}
setthvalue(x) {
this.type = CT.LUA_TTHREAD;
this.value = x;
}
setclLvalue(x) {
this.type = CT.LUA_TLCL;
this.value = x;
}
setclCvalue(x) {
this.type = CT.LUA_TCCL;
this.value = x;
}
sethvalue(x) {
this.type = CT.LUA_TTABLE;
this.value = x;
}
setdeadvalue() {
this.type = LUA_TDEADKEY;
this.value = null;
}
setfrom(tv) { /* in lua C source setobj2t is often used for this */
this.type = tv.type;
this.value = tv.value;
}
tsvalue() {
assert(this.ttisstring());
return this.value;
}
svalue() {
return this.tsvalue().getstr();
}
vslen() {
return this.tsvalue().tsslen();
}
jsstring(from, to) {
return defs.to_jsstring(this.svalue(), from, to);
}
}
const pushobj2s = function(L, tv) {
L.stack[L.top++] = new TValue(tv.type, tv.value);
};
const pushsvalue2s = function(L, ts) {
L.stack[L.top++] = new TValue(CT.LUA_TLNGSTR, ts);
};
/* from stack to (same) stack */
const setobjs2s = function(L, newidx, oldidx) {
L.stack[newidx].setfrom(L.stack[oldidx]);
};
/* to stack (not from same stack) */
const setobj2s = function(L, newidx, oldtv) {
L.stack[newidx].setfrom(oldtv);
};
const setsvalue2s = function(L, newidx, ts) {
L.stack[newidx].setsvalue(ts);
};
const luaO_nilobject = new TValue(CT.LUA_TNIL, null);
Object.freeze(luaO_nilobject);
module.exports.luaO_nilobject = luaO_nilobject;
class LClosure {
constructor(L, n) {
this.id = L.l_G.id_counter++;
this.p = null;
this.nupvalues = n;
this.upvals = new Array(n); /* list of upvalues as UpVals. initialised in luaF_initupvals */
}
}
class CClosure {
constructor(L, f, n) {
this.id = L.l_G.id_counter++;
this.f = f;
this.nupvalues = n;
this.upvalue = new Array(n); /* list of upvalues as TValues */
while (n--) {
this.upvalue[n] = new TValue(CT.LUA_TNIL, null);
}
}
}
class Udata {
constructor(L, size) {
this.id = L.l_G.id_counter++;
this.metatable = null;
this.uservalue = new TValue(CT.LUA_TNIL, null);
this.len = size;
this.data = Object.create(null); // ignores size argument
}
}
/*
** Description of a local variable for function prototypes
** (used for debug information)
*/
class LocVar {
constructor() {
this.varname = null;
this.startpc = NaN; /* first point where variable is active */
this.endpc = NaN; /* first point where variable is dead */
}
}
const RETS = defs.to_luastring("...", true);
const PRE = defs.to_luastring("[string \"");
const POS = defs.to_luastring("\"]");
const luaO_chunkid = function(source, bufflen) {
let l = source.length;
let out;
if (source[0] === char['=']) { /* 'literal' source */
if (l < bufflen) /* small enough? */
out = source.slice(1);
else { /* truncate it */
out = source.slice(1, bufflen);
}
} else if (source[0] === char['@']) { /* file name */
if (l <= bufflen) /* small enough? */
out = source.slice(1);
else { /* add '...' before rest of name */
bufflen -= RETS.length;
out = RETS.concat(source.slice(1 + l - bufflen));
}
} else { /* string; format as [string "source"] */
let nli = source.indexOf(char['\n']); /* find first new line (if any) */
out = PRE; /* add prefix */
bufflen -= PRE.length + RETS.length + POS.length + 1; /* save space for prefix+suffix+'\0' */
if (l < bufflen && nli === -1) { /* small one-line source? */
out = out.concat(source, POS); /* keep it */
} else {
if (nli !== -1) l = nli; /* stop at first newline */
if (l > bufflen) l = bufflen;
out = out.concat(source.slice(0, l), RETS, POS);
}
}
return out;
};
const luaO_hexavalue = function(c) {
if (ljstype.lisdigit(c)) return c - char['0'];
else return (String.fromCharCode(c).toLowerCase().charCodeAt(0) - char['a']) + 10;
};
const UTF8BUFFSZ = 8;
const luaO_utf8desc = function(buff, x) {
let n = 1; /* number of bytes put in buffer (backwards) */
assert(x <= 0x10FFFF);
if (x < 0x80) /* ascii? */
buff[UTF8BUFFSZ - 1] = x;
else { /* need continuation bytes */
let mfb = 0x3f; /* maximum that fits in first byte */
do {
buff[UTF8BUFFSZ - (n++)] = 0x80 | (x & 0x3f);
x >>= 6; /* remove added bits */
mfb >>= 1; /* now there is one less bit available in first byte */
} while (x > mfb); /* still needs continuation byte? */
buff[UTF8BUFFSZ - n] = (~mfb << 1) | x; /* add first byte */
}
return n;
};
/* maximum number of significant digits to read (to avoid overflows
even with single floats) */
const MAXSIGDIG = 30;
/*
** convert an hexadecimal numeric string to a number, following
** C99 specification for 'strtod'
*/
const lua_strx2number = function(s) {
let i = 0;
let dot = char[luaconf.lua_getlocaledecpoint()];
let r = 0.0; /* result (accumulator) */
let sigdig = 0; /* number of significant digits */
let nosigdig = 0; /* number of non-significant digits */
let e = 0; /* exponent correction */
let neg; /* 1 if number is negative */
let hasdot = false; /* true after seen a dot */
while (ljstype.lisspace(s[i])) i++; /* skip initial spaces */
if ((neg = (s[i] === char['-']))) i++; /* check signal */
else if (s[i] === char['+']) i++;
if (!(s[i] === char['0'] && (s[i+1] === char['x'] || s[i+1] === char['X']))) /* check '0x' */
return null; /* invalid format (no '0x') */
for (i += 2; ; i++) { /* skip '0x' and read numeral */
if (s[i] === dot) {
if (hasdot) break; /* second dot? stop loop */
else hasdot = true;
} else if (ljstype.lisxdigit(s[i])) {
if (sigdig === 0 && s[i] === char['0']) /* non-significant digit (zero)? */
nosigdig++;
else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
r = (r * 16) + luaO_hexavalue(s[i]);
else e++; /* too many digits; ignore, but still count for exponent */
if (hasdot) e--; /* decimal digit? correct exponent */
} else break; /* neither a dot nor a digit */
}
if (nosigdig + sigdig === 0) /* no digits? */
return null; /* invalid format */
e *= 4; /* each digit multiplies/divides value by 2^4 */
if (s[i] === char['p'] || s[i] === char['P']) { /* exponent part? */
let exp1 = 0; /* exponent value */
let neg1; /* exponent signal */
i++; /* skip 'p' */
if ((neg1 = (s[i] === char['-']))) i++; /* signal */
else if (s[i] === char['+']) i++;
if (!ljstype.lisdigit(s[i]))
return null; /* invalid; must have at least one digit */
while (ljstype.lisdigit(s[i])) /* read exponent */
exp1 = exp1 * 10 + s[i++] - char['0'];
if (neg1) exp1 = -exp1;
e += exp1;
}
if (neg) r = -r;
while (ljstype.lisspace(s[i])) i++; /* skip trailing spaces */
return i === s.length ? luaconf.ldexp(r, e) : null; /* Only valid if nothing left is s*/
};
const lua_str2number = function(s) {
/* parseFloat ignores trailing junk, validate with regex first */
let str = defs.to_jsstring(s);
if (!/^[\t\v\f \n\r]*[\+\-]?([0-9]+\.?[0-9]*|\.[0-9]*)([eE][\+\-]?[0-9]+)?[\t\v\f \n\r]*$/.test(str))
return null;
let flt = parseFloat(str);
return !isNaN(flt) ? flt : null;
};
const l_str2dloc = function(s, mode) {
return mode === 'x' ? lua_strx2number(s) : lua_str2number(s);
};
const l_str2d = function(s) {
let pidx = /[.xXnN]/g.exec(String.fromCharCode(...s));
pidx = pidx ? pidx.index : null;
let pmode = pidx ? s[pidx] : null;
let mode = pmode ? String.fromCharCode(pmode).toLowerCase() : 0;
if (mode === 'n') /* reject 'inf' and 'nan' */
return null;
let end = l_str2dloc(s, mode); /* try to convert */
if (end === null) { /* failed? may be a different locale */
// throw new Error("Locale not available to handle number"); // TODO
}
return end;
};
const MAXBY10 = Math.floor(llimit.MAX_INT / 10);
const MAXLASTD = llimit.MAX_INT % 10;
const l_str2int = function(s) {
let i = 0;
let a = 0;
let empty = true;
let neg;
while (ljstype.lisspace(s[i])) i++; /* skip initial spaces */
if ((neg = (s[i] === char['-']))) i++;
else if (s[i] === char['+']) i++;
if (s[i] === char['0'] && (s[i+1] === char['x'] || s[i+1] === char['X'])) { /* hex? */
i += 2; /* skip '0x' */
for (; ljstype.lisxdigit(s[i]); i++) {
a = (a * 16 + luaO_hexavalue(s[i]))|0;
empty = false;
}
} else { /* decimal */
for (; ljstype.lisdigit(s[i]); i++) {
let d = s[i] - char['0'];
if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */
return null; /* do not accept it (as integer) */
a = (a * 10 + d)|0;
empty = false;
}
}
while (ljstype.lisspace(s[i])) i++; /* skip trailing spaces */
if (empty || (i !== s.length)) return null; /* something wrong in the numeral */
else {
return (neg ? -a : a)|0;
}
};
const luaO_str2num = function(s) {
let s2i = l_str2int(s);
if (s2i !== null) { /* try as an integer */
return new TValue(CT.LUA_TNUMINT, s2i);
} else { /* else try as a float */
s2i = l_str2d(s);
if (s2i !== null) {
return new TValue(CT.LUA_TNUMFLT, s2i);
} else
return false; /* conversion failed */
}
};
const luaO_utf8esc = function(x) {
let buff = [];
let n = 1; /* number of bytes put in buffer (backwards) */
assert(x <= 0x10ffff);
if (x < 0x80) /* ascii? */
buff[UTF8BUFFSZ - 1] = x;
else { /* need continuation bytes */
let mfb = 0x3f; /* maximum that fits in first byte */
do { /* add continuation bytes */
buff[UTF8BUFFSZ - (n++)] = 0x80 | (x & 0x3f);
x >>= 6; /* remove added bits */
mfb >>= 1; /* now there is one less bit available in first byte */
} while (x > mfb); /* still needs continuation byte? */
buff[UTF8BUFFSZ - n] = (~mfb << 1) | x; /* add first byte */
}
return {
buff: buff,
n: n
};
};
/* this currently returns new TValue instead of modifying */
const luaO_tostring = function(L, obj) {
let buff;
if (obj.ttisinteger())
buff = defs.to_luastring(luaconf.lua_integer2str(obj.value));
else {
let str = luaconf.lua_number2str(obj.value);
buff = defs.to_luastring(str);
// Assume no LUA_COMPAT_FLOATSTRING
if (/^[-0123456789]+$/.test(str)) { /* looks like an int? */
buff.push(char[luaconf.lua_getlocaledecpoint()]);
buff.push(char['0']); /* adds '.0' to result */
}
}
obj.setsvalue(lstring.luaS_bless(L, buff));
};
const pushstr = function(L, str) {
ldo.luaD_inctop(L);
setsvalue2s(L, L.top-1, lstring.luaS_new(L, str));
};
const luaO_pushvfstring = function(L, fmt, argp) {
let n = 0;
let i = 0;
let a = 0;
let e;
while (1) {
e = fmt.indexOf(char['%'], i);
if (e == -1) break;
pushstr(L, fmt.slice(i, e));
switch(fmt[e+1]) {
case char['s']:
let s = argp[a++];
if (s === null) s = defs.to_luastring("(null)", true);
pushstr(L, s);
break;
case char['c']:
let buff = argp[a++];
if (ljstype.lisprint(buff))
pushstr(L, [buff]);
else
luaO_pushfstring(L, defs.to_luastring("<\\%d>", true), buff);
break;
case char['d']:
case char['I']:
ldo.luaD_inctop(L);
L.stack[L.top-1].setivalue(argp[a++]);
luaO_tostring(L, L.stack[L.top-1]);
break;
case char['f']:
ldo.luaD_inctop(L);
L.stack[L.top-1].setfltvalue(argp[a++]);
luaO_tostring(L, L.stack[L.top-1]);
break;
case char['p']:
let v = argp[a++];
if (v instanceof lstate.lua_State ||
v instanceof ltable.Table ||
v instanceof Udata ||
v instanceof LClosure ||
v instanceof CClosure ||
v instanceof lfunc.UpVal) {
pushstr(L, defs.to_luastring("0x"+v.id.toString(16)));
} else {
/* user provided object. no id available */
pushstr(L, defs.to_luastring("<id NYI>"));
}
break;
case char['U']:
pushstr(L, defs.to_luastring(String.fromCodePoint(argp[a++])));
break;
case char['%']:
pushstr(L, [char['%']]);
break;
default: {
ldebug.luaG_runerror(L, defs.to_luastring("invalid option '%%%c' to 'lua_pushfstring'"), fmt[e + 1]);
}
}
n += 2;
i = e + 2;
}
ldo.luaD_checkstack(L, 1);
pushstr(L, fmt.slice(i));
if (n > 0) lvm.luaV_concat(L, n+1);
return L.stack[L.top-1].svalue();
};
const luaO_pushfstring = function(L, fmt, ...argp) {
return luaO_pushvfstring(L, fmt, argp);
};
/*
** converts an integer to a "floating point byte", represented as
** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
** eeeee !== 0 and (xxx) otherwise.
*/
const luaO_int2fb = function(x) {
let e = 0; /* exponent */
if (x < 8) return x;
while (x >= (8 << 4)) { /* coarse steps */
x = (x + 0xf) >> 4; /* x = ceil(x / 16) */
e += 4;
}
while (x >= (8 << 1)) { /* fine steps */
x = (x + 1) >> 1; /* x = ceil(x / 2) */
e++;
}
return ((e+1) << 3) | (x - 8);
};
const intarith = function(L, op, v1, v2) {
switch (op) {
case defs.LUA_OPADD: return (v1 + v2)|0;
case defs.LUA_OPSUB: return (v1 - v2)|0;
case defs.LUA_OPMUL: return Math.imul(v1, v2);
case defs.LUA_OPMOD: return lvm.luaV_mod(L, v1, v2);
case defs.LUA_OPIDIV: return lvm.luaV_div(L, v1, v2);
case defs.LUA_OPBAND: return (v1 & v2);
case defs.LUA_OPBOR: return (v1 | v2);
case defs.LUA_OPBXOR: return (v1 ^ v2);
case defs.LUA_OPSHL: return lvm.luaV_shiftl(v1, v2);
case defs.LUA_OPSHR: return lvm.luaV_shiftl(v1, -v2);
case defs.LUA_OPUNM: return (0 - v1)|0;
case defs.LUA_OPBNOT: return (~0 ^ v1);
default: assert(0);
}
};
const numarith = function(L, op, v1, v2) {
switch (op) {
case defs.LUA_OPADD: return v1 + v2;
case defs.LUA_OPSUB: return v1 - v2;
case defs.LUA_OPMUL: return v1 * v2;
case defs.LUA_OPDIV: return v1 / v2;
case defs.LUA_OPPOW: return Math.pow(v1, v2);
case defs.LUA_OPIDIV: return Math.floor(v1 / v2);
case defs.LUA_OPUNM: return -v1;
case defs.LUA_OPMOD: return llimit.luai_nummod(L, v1, v2);
default: assert(0);
}
};
const luaO_arith = function(L, op, p1, p2, p3) {
let res = (typeof p3 === "number") ? L.stack[p3] : p3; /* FIXME */
switch (op) {
case defs.LUA_OPBAND: case defs.LUA_OPBOR: case defs.LUA_OPBXOR:
case defs.LUA_OPSHL: case defs.LUA_OPSHR:
case defs.LUA_OPBNOT: { /* operate only on integers */
let i1, i2;
if ((i1 = lvm.tointeger(p1)) !== false && (i2 = lvm.tointeger(p2)) !== false) {
res.setivalue(intarith(L, op, i1, i2));
return;
}
else break; /* go to the end */
}
case defs.LUA_OPDIV: case defs.LUA_OPPOW: { /* operate only on floats */
let n1, n2;
if ((n1 = lvm.tonumber(p1)) !== false && (n2 = lvm.tonumber(p2)) !== false) {
res.setfltvalue(numarith(L, op, n1, n2));
return;
}
else break; /* go to the end */
}
default: { /* other operations */
let n1, n2;
if (p1.ttisinteger() && p2.ttisinteger()) {
res.setivalue(intarith(L, op, p1.value, p2.value));
return;
}
else if ((n1 = lvm.tonumber(p1)) !== false && (n2 = lvm.tonumber(p2)) !== false) {
res.setfltvalue(numarith(L, op, n1, n2));
return;
}
else break; /* go to the end */
}
}
/* could not perform raw operation; try metamethod */
assert(L !== null); /* should not fail when folding (compile time) */
ltm.luaT_trybinTM(L, p1, p2, p3, (op - defs.LUA_OPADD) + ltm.TMS.TM_ADD);
};
module.exports.CClosure = CClosure;
module.exports.LClosure = LClosure;
module.exports.LUA_TDEADKEY = LUA_TDEADKEY;
module.exports.LUA_TPROTO = LUA_TPROTO;
module.exports.LocVar = LocVar;
module.exports.TValue = TValue;
module.exports.Udata = Udata;
module.exports.UTF8BUFFSZ = UTF8BUFFSZ;
module.exports.luaO_arith = luaO_arith;
module.exports.luaO_chunkid = luaO_chunkid;
module.exports.luaO_hexavalue = luaO_hexavalue;
module.exports.luaO_int2fb = luaO_int2fb;
module.exports.luaO_pushfstring = luaO_pushfstring;
module.exports.luaO_pushvfstring = luaO_pushvfstring;
module.exports.luaO_str2num = luaO_str2num;
module.exports.luaO_tostring = luaO_tostring;
module.exports.luaO_utf8desc = luaO_utf8desc;
module.exports.luaO_utf8esc = luaO_utf8esc;
module.exports.numarith = numarith;
module.exports.pushobj2s = pushobj2s;
module.exports.pushsvalue2s = pushsvalue2s;
module.exports.setobjs2s = setobjs2s;
module.exports.setobj2s = setobj2s;
module.exports.setsvalue2s = setsvalue2s;
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const LUAI_MAXCCALLS = 200;
module.exports.LUAI_MAXCCALLS = LUAI_MAXCCALLS;
const LUA_MAXINTEGER = 2147483647;
module.exports.LUA_MAXINTEGER = LUA_MAXINTEGER;
const LUA_MININTEGER = -2147483648;
module.exports.LUA_MININTEGER = LUA_MININTEGER;
const luai_nummod = function(L, a, b) {
let m = a % b;
if ((m*b) < 0)
m += b;
return m;
};
module.exports.luai_nummod = luai_nummod;
// If later integers are more than 32bit, LUA_MAXINTEGER will then be != MAX_INT
const MAX_INT = 2147483647;
module.exports.MAX_INT = MAX_INT;
const MIN_INT = -2147483648;
module.exports.MIN_INT = MIN_INT;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const lua = __webpack_require__(3);
/* key, in the registry, for table of loaded modules */
const LUA_LOADED_TABLE = "_LOADED";
/* key, in the registry, for table of preloaded loaders */
const LUA_PRELOAD_TABLE = "_PRELOAD";
const LUA_FILEHANDLE = lua.to_luastring("FILE*", true);
const LUAL_NUMSIZES = 4*16 + 8;
class luaL_Buffer {
constructor() {
this.b = null;
this.L = null;
}
}
const LEVELS1 = 10; /* size of the first part of the stack */
const LEVELS2 = 11; /* size of the second part of the stack */
/*
** search for 'objidx' in table at index -1.
** return 1 + string at top if find a good name.
*/
const findfield = function(L, objidx, level) {
if (level === 0 || !lua.lua_istable(L, -1))
return 0; /* not found */
lua.lua_pushnil(L); /* start 'next' loop */
while (lua.lua_next(L, -2)) { /* for each pair in table */
if (lua.lua_type(L, -2) === lua.LUA_TSTRING) { /* ignore non-string keys */
if (lua.lua_rawequal(L, objidx, -1)) { /* found object? */
lua.lua_pop(L, 1); /* remove value (but keep name) */
return 1;
} else if (findfield(L, objidx, level - 1)) { /* try recursively */
lua.lua_remove(L, -2); /* remove table (but keep name) */
lua.lua_pushliteral(L, ".");
lua.lua_insert(L, -2); /* place '.' between the two names */
lua.lua_concat(L, 3);
return 1;
}
}
lua.lua_pop(L, 1); /* remove value */
}
return 0; /* not found */
};
/*
** Search for a name for a function in all loaded modules
*/
const pushglobalfuncname = function(L, ar) {
let top = lua.lua_gettop(L);
lua.lua_getinfo(L, ['f'.charCodeAt(0)], ar); /* push function */
lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(LUA_LOADED_TABLE, true));
if (findfield(L, top + 1, 2)) {
let name = lua.lua_tostring(L, -1);
if (lua.to_jsstring(name).startsWith("_G.")) { /* name start with '_G.'? */
lua.lua_pushstring(L, name.slice(3)); /* push name without prefix */
lua.lua_remove(L, -2); /* remove original name */
}
lua.lua_copy(L, -1, top + 1); /* move name to proper place */
lua.lua_pop(L, 2); /* remove pushed values */
return 1;
} else {
lua.lua_settop(L, top); /* remove function and global table */
return 0;
}
};
const pushfuncname = function(L, ar) {
if (pushglobalfuncname(L, ar)) { /* try first a global name */
lua.lua_pushfstring(L, lua.to_luastring("function '%s'"), lua.lua_tostring(L, -1));
lua.lua_remove(L, -2); /* remove name */
}
else if (ar.namewhat.length !== 0) /* is there a name from code? */
lua.lua_pushfstring(L, lua.to_luastring("%s '%s'"), ar.namewhat, ar.name); /* use it */
else if (ar.what && ar.what[0] === 'm'.charCodeAt(0)) /* main? */
lua.lua_pushliteral(L, "main chunk");
else if (ar.what && ar.what[0] != 'C'.charCodeAt(0)) /* for Lua functions, use <file:line> */
lua.lua_pushfstring(L, lua.to_luastring("function <%s:%d>"), ar.short_src, ar.linedefined);
else /* nothing left... */
lua.lua_pushliteral(L, "?");
};
const lastlevel = function(L) {
let ar = new lua.lua_Debug();
let li = 1;
let le = 1;
/* find an upper bound */
while (lua.lua_getstack(L, le, ar)) { li = le; le *= 2; }
/* do a binary search */
while (li < le) {
let m = Math.floor((li + le)/2);
if (lua.lua_getstack(L, m, ar)) li = m + 1;
else le = m;
}
return le - 1;
};
const luaL_traceback = function(L, L1, msg, level) {
let ar = new lua.lua_Debug();
let top = lua.lua_gettop(L);
let last = lastlevel(L1);
let n1 = last - level > LEVELS1 + LEVELS2 ? LEVELS1 : -1;
if (msg)
lua.lua_pushfstring(L, lua.to_luastring("%s\n"), msg);
luaL_checkstack(L, 10, null);
lua.lua_pushliteral(L, "stack traceback:");
while (lua.lua_getstack(L1, level++, ar)) {
if (n1-- === 0) { /* too many levels? */
lua.lua_pushliteral(L, "\n\t..."); /* add a '...' */
level = last - LEVELS2 + 1; /* and skip to last ones */
} else {
lua.lua_getinfo(L1, lua.to_luastring("Slnt", true), ar);
lua.lua_pushfstring(L, lua.to_luastring("\n\t%s:"), ar.short_src);
if (ar.currentline > 0)
lua.lua_pushliteral(L, `${ar.currentline}:`);
lua.lua_pushliteral(L, " in ");
pushfuncname(L, ar);
if (ar.istailcall)
lua.lua_pushliteral(L, "\n\t(...tail calls..)");
lua.lua_concat(L, lua.lua_gettop(L) - top);
}
}
lua.lua_concat(L, lua.lua_gettop(L) - top);
};
const panic = function(L) {
throw new Error(`PANIC: unprotected error in call to Lua API (${lua.lua_tojsstring(L, -1)})`);
};
const luaL_argerror = function(L, arg, extramsg) {
let ar = new lua.lua_Debug();
if (!lua.lua_getstack(L, 0, ar)) /* no stack frame? */
return luaL_error(L, lua.to_luastring("bad argument #%d (%s)"), arg, extramsg);
lua.lua_getinfo(L, ['n'.charCodeAt(0)], ar);
if (lua.to_jsstring(ar.namewhat) === "method") {
arg--; /* do not count 'self' */
if (arg === 0) /* error is in the self argument itself? */
return luaL_error(L, lua.to_luastring("calling '%s' on bad self (%s)"), ar.name, extramsg);
}
if (ar.name === null)
ar.name = pushglobalfuncname(L, ar) ? lua.lua_tostring(L, -1) : ["?".charCodeAt(0)];
return luaL_error(L, lua.to_luastring("bad argument #%d to '%s' (%s)"), arg, ar.name, extramsg);
};
const typeerror = function(L, arg, tname) {
let typearg;
if (luaL_getmetafield(L, arg, lua.to_luastring("__name", true)) === lua.LUA_TSTRING)
typearg = lua.lua_tostring(L, -1);
else if (lua.lua_type(L, arg) === lua.LUA_TLIGHTUSERDATA)
typearg = lua.to_luastring("light userdata", true);
else
typearg = luaL_typename(L, arg);
let msg = lua.lua_pushfstring(L, lua.to_luastring("%s expected, got %s"), tname, typearg);
return luaL_argerror(L, arg, msg);
};
const luaL_where = function(L, level) {
let ar = new lua.lua_Debug();
if (lua.lua_getstack(L, level, ar)) {
lua.lua_getinfo(L, lua.to_luastring("Sl", true), ar);
if (ar.currentline > 0) {
lua.lua_pushfstring(L, lua.to_luastring("%s:%d: "), ar.short_src, ar.currentline);
return;
}
}
lua.lua_pushstring(L, []);
};
const luaL_error = function(L, fmt, ...argp) {
luaL_where(L, 1);
lua.lua_pushvfstring(L, fmt, argp);
lua.lua_concat(L, 2);
return lua.lua_error(L);
};
/* Unlike normal lua, we pass in an error object */
const luaL_fileresult = function(L, stat, fname, e) {
if (stat) {
lua.lua_pushboolean(L, 1);
return 1;
} else {
lua.lua_pushnil(L);
if (fname)
lua.lua_pushstring(L, lua.to_luastring(`${lua.to_jsstring(fname)}: ${e.message}`));
else
lua.lua_pushstring(L, lua.to_luastring(e.message));
lua.lua_pushinteger(L, -e.errno);
return 3;
}
};
/* Unlike normal lua, we pass in an error object */
const luaL_execresult = function(L, e) {
let what, stat;
if (e === null) {
lua.lua_pushboolean(L, 1);
lua.lua_pushliteral(L, "exit");
lua.lua_pushinteger(L, 0);
return 3;
} else if (e.status) {
what = "exit";
stat = e.status;
} else if (e.signal) {
what = "signal";
stat = e.signal;
} else {
/* XXX: node seems to have e.errno as a string instead of a number */
return luaL_fileresult(L, 0, null, e);
}
lua.lua_pushnil(L);
lua.lua_pushliteral(L, what);
lua.lua_pushinteger(L, stat);
return 3;
};
const luaL_getmetatable = function(L, n) {
return lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, n);
};
const luaL_newmetatable = function(L, tname) {
if (luaL_getmetatable(L, tname) !== lua.LUA_TNIL) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
lua.lua_pop(L, 1);
lua.lua_createtable(L, 0, 2); /* create metatable */
lua.lua_pushstring(L, tname);
lua.lua_setfield(L, -2, lua.to_luastring("__name")); /* metatable.__name = tname */
lua.lua_pushvalue(L, -1);
lua.lua_setfield(L, lua.LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
return 1;
};
const luaL_setmetatable = function(L, tname) {
luaL_getmetatable(L, tname);
lua.lua_setmetatable(L, -2);
};
const luaL_testudata = function(L, ud, tname) {
let p = lua.lua_touserdata(L, ud);
if (p !== null) { /* value is a userdata? */
if (lua.lua_getmetatable(L, ud)) { /* does it have a metatable? */
luaL_getmetatable(L, tname); /* get correct metatable */
if (!lua.lua_rawequal(L, -1, -2)) /* not the same? */
p = null; /* value is a userdata with wrong metatable */
lua.lua_pop(L, 2); /* remove both metatables */
return p;
}
}
return null; /* value is not a userdata with a metatable */
};
const luaL_checkudata = function(L, ud, tname) {
let p = luaL_testudata(L, ud, tname);
if (p === null) typeerror(L, ud, tname);
return p;
};
const luaL_checkoption = function(L, arg, def, lst) {
let name = def ? luaL_optstring(L, arg, def) : luaL_checkstring(L, arg);
for (let i = 0; lst[i]; i++)
if (lst[i].join('|') === name.join('|'))
return i;
return luaL_argerror(L, arg, lua.lua_pushfstring(L, lua.to_luastring("invalid option '%s'"), name));
};
const tag_error = function(L, arg, tag) {
typeerror(L, arg, lua.lua_typename(L, tag));
};
const luaL_newstate = function() {
let L = lua.lua_newstate();
if (L) lua.lua_atpanic(L, panic);
return L;
};
const luaL_typename = function(L, i) {
return lua.lua_typename(L, lua.lua_type(L, i));
};
const luaL_argcheck = function(L, cond, arg, extramsg) {
if (!cond) luaL_argerror(L, arg, extramsg);
};
const luaL_checkany = function(L, arg) {
if (lua.lua_type(L, arg) === lua.LUA_TNONE)
luaL_argerror(L, arg, lua.to_luastring("value expected", true));
};
const luaL_checktype = function(L, arg, t) {
if (lua.lua_type(L, arg) !== t)
tag_error(L, arg, t);
};
const luaL_checkstring = function(L, n) {
return luaL_checklstring(L, n, null);
};
const luaL_checklstring = function(L, arg) {
let s = lua.lua_tolstring(L, arg);
if (s === null || s === undefined) tag_error(L, arg, lua.LUA_TSTRING);
return s;
};
const luaL_optlstring = function(L, arg, def) {
if (lua.lua_type(L, arg) <= 0) {
return def;
} else return luaL_checklstring(L, arg);
};
const luaL_optstring = luaL_optlstring;
const interror = function(L, arg) {
if (lua.lua_isnumber(L, arg))
luaL_argerror(L, arg, lua.to_luastring("number has no integer representation", true));
else
tag_error(L, arg, lua.LUA_TNUMBER);
};
const luaL_checknumber = function(L, arg) {
let d = lua.lua_tonumberx(L, arg);
if (d === false)
tag_error(L, arg, lua.LUA_TNUMBER);
return d;
};
const luaL_optnumber = function(L, arg, def) {
return luaL_opt(L, luaL_checknumber, arg, def);
};
const luaL_checkinteger = function(L, arg) {
let d = lua.lua_tointeger(L, arg);
if (d === false)
interror(L, arg);
return d;
};
const luaL_optinteger = function(L, arg, def) {
return luaL_opt(L, luaL_checkinteger, arg, def);
};
const luaL_prepbuffsize = function(B, sz) {
return B;
};
const luaL_buffinit = function(L, B) {
B.L = L;
B.b = [];
};
const luaL_buffinitsize = function(L, B, sz) {
luaL_buffinit(L, B);
return B;
};
const LUAL_BUFFERSIZE = 8192;
const luaL_prepbuffer = function(B) {
return luaL_prepbuffsize(B, LUAL_BUFFERSIZE);
};
const luaL_addlstring = function(B, s, l) {
B.b = B.b.concat(s.slice(0, l));
};
const luaL_addstring = luaL_addlstring;
const luaL_pushresult = function(B) {
let L = B.L;
lua.lua_pushstring(L, B.b);
};
const luaL_addchar = function(B, c) {
B.b.push(c);
};
const luaL_addsize = function(B, s) {
B.n += s;
};
const luaL_pushresultsize = function(B, sz) {
luaL_addsize(B, sz);
luaL_pushresult(B);
};
const luaL_addvalue = function(B) {
let L = B.L;
let s = lua.lua_tostring(L, -1);
// TODO: buffonstack ? necessary ?
luaL_addstring(B, s);
lua.lua_remove(L, -1);
};
const luaL_opt = function(L, f, n, d) {
return lua.lua_type(L, n) <= 0 ? d : f(L, n);
};
const getS = function(L, ud) {
let s = ud.string;
ud.string = null;
return s;
};
const luaL_loadbufferx = function(L, buff, size, name, mode) {
return lua.lua_load(L, getS, {string: buff}, name, mode);
};
const luaL_loadbuffer = function(L, s, sz, n) {
return luaL_loadbufferx(L, s, sz, n, null);
};
const luaL_loadstring = function(L, s) {
return luaL_loadbuffer(L, s, s.length, s);
};
const luaL_dostring = function(L, s) {
return (luaL_loadstring(L, s) || lua.lua_pcall(L, 0, lua.LUA_MULTRET, 0));
};
const luaL_getmetafield = function(L, obj, event) {
if (!lua.lua_getmetatable(L, obj))
return lua.LUA_TNIL;
else {
lua.lua_pushstring(L, event);
let tt = lua.lua_rawget(L, -2);
if (tt === lua.LUA_TNIL)
lua.lua_pop(L, 2);
return tt;
}
};
const luaL_callmeta = function(L, obj, event) {
obj = lua.lua_absindex(L, obj);
if (luaL_getmetafield(L, obj, event) === lua.LUA_TNIL)
return false;
lua.lua_pushvalue(L, obj);
lua.lua_call(L, 1, 1);
return true;
};
const luaL_len = function(L, idx) {
lua.lua_len(L, idx);
let l = lua.lua_tointegerx(L, -1);
if (l === false)
luaL_error(L, lua.to_luastring("object length is not an integer", true));
lua.lua_pop(L, 1); /* remove object */
return l;
};
const luaL_tolstring = function(L, idx) {
if (luaL_callmeta(L, idx, lua.to_luastring("__tostring", true))) {
if (!lua.lua_isstring(L, -1))
luaL_error(L, lua.to_luastring("'__tostring' must return a string", true));
} else {
let t = lua.lua_type(L, idx);
switch(t) {
case lua.LUA_TNUMBER: {
if (lua.lua_isinteger(L, idx))
lua.lua_pushfstring(L, lua.to_luastring("%I"), lua.lua_tointeger(L, idx));
else
lua.lua_pushfstring(L, lua.to_luastring("%f"), lua.lua_tonumber(L, idx));
break;
}
case lua.LUA_TSTRING:
lua.lua_pushvalue(L, idx);
break;
case lua.LUA_TBOOLEAN:
lua.lua_pushliteral(L, (lua.lua_toboolean(L, idx) ? "true" : "false"));
break;
case lua.LUA_TNIL:
lua.lua_pushliteral(L, "nil");
break;
default:
let tt = luaL_getmetafield(L, idx, lua.to_luastring("__name", true));
let kind = tt === lua.LUA_TSTRING ? lua.lua_tostring(L, -1) : luaL_typename(L, idx);
lua.lua_pushfstring(L, lua.to_luastring("%s: %p"), kind, lua.lua_topointer(L, idx));
if (tt !== lua.LUA_TNIL)
lua.lua_remove(L, -2);
break;
}
}
return lua.lua_tolstring(L, -1);
};
/*
** Stripped-down 'require': After checking "loaded" table, calls 'openf'
** to open a module, registers the result in 'package.loaded' table and,
** if 'glb' is true, also registers the result in the global table.
** Leaves resulting module on the top.
*/
const luaL_requiref = function(L, modname, openf, glb) {
luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(LUA_LOADED_TABLE));
lua.lua_getfield(L, -1, modname); /* LOADED[modname] */
if (!lua.lua_toboolean(L, -1)) { /* package not already loaded? */
lua.lua_pop(L, 1); /* remove field */
lua.lua_pushcfunction(L, openf);
lua.lua_pushstring(L, modname); /* argument to open function */
lua.lua_call(L, 1, 1); /* call 'openf' to open module */
lua.lua_pushvalue(L, -1); /* make copy of module (call result) */
lua.lua_setfield(L, -3, modname); /* LOADED[modname] = module */
}
lua.lua_remove(L, -2); /* remove LOADED table */
if (glb) {
lua.lua_pushvalue(L, -1); /* copy of module */
lua.lua_setglobal(L, modname); /* _G[modname] = module */
}
};
const find_subarray = function(arr, subarr, from_index) {
var i = from_index >>> 0,
sl = subarr.length,
l = arr.length + 1 - sl;
loop: for (; i < l; i++) {
for (let j = 0; j < sl; j++)
if (arr[i+j] !== subarr[j])
continue loop;
return i;
}
return -1;
};
const luaL_gsub = function(L, s, p, r) {
let wild;
let b = [];
while ((wild = find_subarray(s, p)) >= 0) {
b.push(...s.slice(0, wild)); /* push prefix */
b.push(...r); /* push replacement in place of pattern */
s = s.slice(wild + p.length); /* continue after 'p' */
}
b.push(...s); /* push last suffix */
lua.lua_pushstring(L, b);
return lua.lua_tostring(L, -1);
};
/*
** ensure that stack[idx][fname] has a table and push that table
** into the stack
*/
const luaL_getsubtable = function(L, idx, fname) {
if (lua.lua_getfield(L, idx, fname) === lua.LUA_TTABLE)
return true; /* table already there */
else {
lua.lua_pop(L, 1); /* remove previous result */
idx = lua.lua_absindex(L, idx);
lua.lua_newtable(L);
lua.lua_pushvalue(L, -1); /* copy to be left at top */
lua.lua_setfield(L, idx, fname); /* assign new table to field */
return false; /* false, because did not find table there */
}
};
/*
** set functions from list 'l' into table at top - 'nup'; each
** function gets the 'nup' elements at the top as upvalues.
** Returns with only the table at the stack.
*/
const luaL_setfuncs = function(L, l, nup) {
luaL_checkstack(L, nup, lua.to_luastring("too many upvalues", true));
for (let lib in l) { /* fill the table with given functions */
for (let i = 0; i < nup; i++) /* copy upvalues to the top */
lua.lua_pushvalue(L, -nup);
lua.lua_pushcclosure(L, l[lib], nup); /* closure with those upvalues */
lua.lua_setfield(L, -(nup + 2), lua.to_luastring(lib));
}
lua.lua_pop(L, nup); /* remove upvalues */
};
/*
** Ensures the stack has at least 'space' extra slots, raising an error
** if it cannot fulfill the request. (The error handling needs a few
** extra slots to format the error message. In case of an error without
** this extra space, Lua will generate the same 'stack overflow' error,
** but without 'msg'.)
*/
const luaL_checkstack = function(L, space, msg) {
if (!lua.lua_checkstack(L, space)) {
if (msg)
luaL_error(L, lua.to_luastring("stack overflow (%s)"), msg);
else
luaL_error(L, lua.to_luastring('stack overflow', true));
}
};
const luaL_newlibtable = function(L) {
lua.lua_createtable(L);
};
const luaL_newlib = function(L, l) {
lua.lua_createtable(L);
luaL_setfuncs(L, l, 0);
};
/* predefined references */
const LUA_NOREF = -2;
const LUA_REFNIL = -1;
const luaL_ref = function(L, t) {
let ref;
if (lua.lua_isnil(L, -1)) {
lua.lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* 'nil' has a unique fixed reference */
}
t = lua.lua_absindex(L, t);
lua.lua_rawgeti(L, t, 0); /* get first free element */
ref = lua.lua_tointeger(L, -1); /* ref = t[freelist] */
lua.lua_pop(L, 1); /* remove it from stack */
if (ref !== 0) { /* any free element? */
lua.lua_rawgeti(L, t, ref); /* remove it from list */
lua.lua_rawseti(L, t, 0); /* (t[freelist] = t[ref]) */
}
else /* no free elements */
ref = lua.lua_rawlen(L, t) + 1; /* get a new reference */
lua.lua_rawseti(L, t, ref);
return ref;
};
const luaL_unref = function(L, t, ref) {
if (ref >= 0) {
t = lua.lua_absindex(L, t);
lua.lua_rawgeti(L, t, 0);
lua.lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */
lua.lua_pushinteger(L, ref);
lua.lua_rawseti(L, t, 0); /* t[freelist] = ref */
}
};
const errfile = function(L, what, fnameindex, error) {
let serr = error.message;
let filename = lua.lua_tostring(L, fnameindex).slice(1);
lua.lua_pushstring(L, lua.to_luastring(`cannot ${what} ${lua.to_jsstring(filename)}: ${serr}`));
lua.lua_remove(L, fnameindex);
return lua.LUA_ERRFILE;
};
let getc;
const utf8_bom = [0XEF, 0XBB, 0XBF]; /* UTF-8 BOM mark */
const skipBOM = function(lf) {
lf.n = 0;
let c;
let p = 0;
do {
c = getc(lf);
if (c === null || c !== utf8_bom[p]) return c;
p++;
lf.buff[lf.n++] = c; /* to be read by the parser */
} while (p < utf8_bom.length);
lf.n = 0; /* prefix matched; discard it */
return getc(lf); /* return next character */
};
/*
** reads the first character of file 'f' and skips an optional BOM mark
** in its beginning plus its first line if it starts with '#'. Returns
** true if it skipped the first line. In any case, '*cp' has the
** first "valid" character of the file (after the optional BOM and
** a first-line comment).
*/
const skipcomment = function(lf) {
let c = skipBOM(lf);
if (c === '#'.charCodeAt(0)) { /* first line is a comment (Unix exec. file)? */
do { /* skip first line */
c = getc(lf);
} while (c && c !== '\n'.charCodeAt(0));
return {
skipped: true,
c: getc(lf) /* skip end-of-line, if present */
};
} else {
return {
skipped: false,
c: c
};
}
};
let luaL_loadfilex;
class LoadF {
constructor() {
this.n = NaN; /* number of pre-read characters */
this.f = null; /* file being read */
this.buff = true ? new Array(1024) : new Buffer(1024); /* area for reading file */
this.pos = 0; /* current position in file */
this.err = void 0;
}
}
if (true) {
const getF = function(L, ud) {
let lf = ud;
if (lf.f !== null && lf.n > 0) { /* are there pre-read characters to be read? */
let bytes = lf.n; /* return them (chars already in buffer) */
lf.n = 0; /* no more pre-read characters */
lf.f = lf.f.slice(lf.pos); /* we won't use lf.buff anymore */
return lf.buff.slice(0, bytes);
}
let f = lf.f;
lf.f = null;
return f;
};
getc = function(lf) {
return lf.pos < lf.f.length ? lf.f[lf.pos++] : null;
};
luaL_loadfilex = function(L, filename, mode) {
let lf = new LoadF();
let fnameindex = lua.lua_gettop(L) + 1; /* index of filename on the stack */
if (filename === null) {
throw new Error("Can't read stdin in the browser");
} else {
lua.lua_pushfstring(L, lua.to_luastring("@%s"), filename);
let jsfilename = lua.to_jsstring(filename);
let xhr = new XMLHttpRequest();
xhr.open("GET", jsfilename, false);
// TODO: find a way to load bytes instead of js string
xhr.send();
if (xhr.status >= 200 && xhr.status <= 299) {
/* TODO: Synchronous xhr alway return a js string */
lf.f = lua.to_luastring(xhr.response);
} else {
lf.err = xhr.status;
return errfile(L, "open", fnameindex, { message: `${xhr.status}: ${xhr.statusText}` });
}
}
let com = skipcomment(lf);
/* check for signature first, as we don't want to add line number corrections in binary case */
if (com.c === lua.LUA_SIGNATURE.charCodeAt(0) && filename) { /* binary file? */
/* no need to re-open in node.js */
} else if (com.skipped) { /* read initial portion */
lf.buff[lf.n++] = '\n'.charCodeAt(0); /* add line to correct line numbers */
}
if (com.c !== null)
lf.buff[lf.n++] = com.c; /* 'c' is the first character of the stream */
let status = lua.lua_load(L, getF, lf, lua.lua_tostring(L, -1), mode);
let readstatus = lf.err;
if (readstatus) {
lua.lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
return errfile(L, "read", fnameindex, readstatus);
}
lua.lua_remove(L, fnameindex);
return status;
};
} else {
const fs = require('fs');
const getF = function(L, ud) {
let lf = ud;
let bytes = 0;
if (lf.n > 0) { /* are there pre-read characters to be read? */
bytes = lf.n; /* return them (chars already in buffer) */
lf.n = 0; /* no more pre-read characters */
} else { /* read a block from file */
lf.buff.fill(0);
try {
bytes = fs.readSync(lf.f, lf.buff, 0, lf.buff.length, lf.pos); /* read block */
} catch(e) {
lf.err = e;
bytes = 0;
}
lf.pos += bytes;
}
if (bytes > 0)
return lf.buff.slice(0, bytes); /* slice on a node.js Buffer is 'free' */
else return null;
};
getc = function(lf) {
let b = new Buffer(1);
let bytes = fs.readSync(lf.f, b, 0, 1, lf.pos);
lf.pos += bytes;
return bytes > 0 ? b.readUInt8() : null;
};
luaL_loadfilex = function(L, filename, mode) {
let lf = new LoadF();
let fnameindex = lua.lua_gettop(L) + 1; /* index of filename on the stack */
if (filename === null) {
lua.lua_pushliteral(L, "=stdin");
lf.f = process.stdin.fd;
} else {
lua.lua_pushfstring(L, lua.to_luastring("@%s"), filename);
try {
let jsfilename = lua.to_jsstring(filename);
lf.f = fs.openSync(jsfilename, "r");
if (!fs.fstatSync(lf.f).isFile())
throw new Error(`${jsfilename} is not a readable file`);
} catch (e) {
return errfile(L, "open", fnameindex, e);
}
}
let com = skipcomment(lf);
/* check for signature first, as we don't want to add line number corrections in binary case */
if (com.c === lua.LUA_SIGNATURE.charCodeAt(0) && filename) { /* binary file? */
/* no need to re-open in node.js */
} else if (com.skipped) { /* read initial portion */
lf.buff[lf.n++] = '\n'.charCodeAt(0); /* add line to correct line numbers */
}
if (com.c !== null)
lf.buff[lf.n++] = com.c; /* 'c' is the first character of the stream */
let status = lua.lua_load(L, getF, lf, lua.lua_tostring(L, -1), mode);
let readstatus = lf.err;
if (filename) try { fs.closeSync(lf.f); } catch(e) {} /* close file (even in case of errors) */
if (readstatus) {
lua.lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
return errfile(L, "read", fnameindex, readstatus);
}
lua.lua_remove(L, fnameindex);
return status;
};
}
const luaL_loadfile = function(L, filename) {
return luaL_loadfilex(L, filename, null);
};
const luaL_dofile = function(L, filename) {
return (luaL_loadfile(L, filename) || lua.lua_pcall(L, 0, lua.LUA_MULTRET, 0));
};
const lua_writestringerror = function(s) {
if (process.stderr) process.stderr.write(s);
else console.error(s);
};
const luaL_checkversion = function(L) {
let ver = lua.LUA_VERSION_NUM;
let sz = LUAL_NUMSIZES;
let v = lua.lua_version(L);
if (sz != LUAL_NUMSIZES) /* check numeric types */
luaL_error(L, lua.to_luastring("core and library have incompatible numeric types"));
if (v != lua.lua_version(null))
luaL_error(L, lua.to_luastring("multiple Lua VMs detected"));
else if (v !== ver)
luaL_error(L, lua.to_luastring("version mismatch: app. needs %f, Lua core provides %f"), ver, v);
};
module.exports.LUA_FILEHANDLE = LUA_FILEHANDLE;
module.exports.LUA_LOADED_TABLE = LUA_LOADED_TABLE;
module.exports.LUA_NOREF = LUA_NOREF;
module.exports.LUA_PRELOAD_TABLE = LUA_PRELOAD_TABLE;
module.exports.LUA_REFNIL = LUA_REFNIL;
module.exports.luaL_Buffer = luaL_Buffer;
module.exports.luaL_addchar = luaL_addchar;
module.exports.luaL_addlstring = luaL_addlstring;
module.exports.luaL_addsize = luaL_addsize;
module.exports.luaL_addstring = luaL_addstring;
module.exports.luaL_addvalue = luaL_addvalue;
module.exports.luaL_argcheck = luaL_argcheck;
module.exports.luaL_argerror = luaL_argerror;
module.exports.luaL_buffinit = luaL_buffinit;
module.exports.luaL_buffinitsize = luaL_buffinitsize;
module.exports.luaL_callmeta = luaL_callmeta;
module.exports.luaL_checkany = luaL_checkany;
module.exports.luaL_checkinteger = luaL_checkinteger;
module.exports.luaL_checklstring = luaL_checklstring;
module.exports.luaL_checknumber = luaL_checknumber;
module.exports.luaL_checkoption = luaL_checkoption;
module.exports.luaL_checkstack = luaL_checkstack;
module.exports.luaL_checkstring = luaL_checkstring;
module.exports.luaL_checktype = luaL_checktype;
module.exports.luaL_checkudata = luaL_checkudata;
module.exports.luaL_checkversion = luaL_checkversion;
module.exports.luaL_dofile = luaL_dofile;
module.exports.luaL_dostring = luaL_dostring;
module.exports.luaL_error = luaL_error;
module.exports.luaL_execresult = luaL_execresult;
module.exports.luaL_fileresult = luaL_fileresult;
module.exports.luaL_getmetafield = luaL_getmetafield;
module.exports.luaL_getmetatable = luaL_getmetatable;
module.exports.luaL_getsubtable = luaL_getsubtable;
module.exports.luaL_gsub = luaL_gsub;
module.exports.luaL_len = luaL_len;
module.exports.luaL_loadbuffer = luaL_loadbuffer;
module.exports.luaL_loadbufferx = luaL_loadbufferx;
module.exports.luaL_loadfile = luaL_loadfile;
module.exports.luaL_loadfilex = luaL_loadfilex;
module.exports.luaL_loadstring = luaL_loadstring;
module.exports.luaL_newlib = luaL_newlib;
module.exports.luaL_newlibtable = luaL_newlibtable;
module.exports.luaL_newmetatable = luaL_newmetatable;
module.exports.luaL_newstate = luaL_newstate;
module.exports.luaL_opt = luaL_opt;
module.exports.luaL_optinteger = luaL_optinteger;
module.exports.luaL_optlstring = luaL_optlstring;
module.exports.luaL_optnumber = luaL_optnumber;
module.exports.luaL_optstring = luaL_optstring;
module.exports.luaL_prepbuffer = luaL_prepbuffer;
module.exports.luaL_prepbuffsize = luaL_prepbuffsize;
module.exports.luaL_pushresult = luaL_pushresult;
module.exports.luaL_pushresultsize = luaL_pushresultsize;
module.exports.luaL_ref = luaL_ref;
module.exports.luaL_requiref = luaL_requiref;
module.exports.luaL_setfuncs = luaL_setfuncs;
module.exports.luaL_setmetatable = luaL_setmetatable;
module.exports.luaL_testudata = luaL_testudata;
module.exports.luaL_tolstring = luaL_tolstring;
module.exports.luaL_traceback = luaL_traceback;
module.exports.luaL_typename = luaL_typename;
module.exports.luaL_unref = luaL_unref;
module.exports.luaL_where = luaL_where;
module.exports.lua_writestringerror = lua_writestringerror;
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const LUAI_MAXCCALLS = 200;
module.exports.LUAI_MAXCCALLS = LUAI_MAXCCALLS;
const LUA_MAXINTEGER = 2147483647;
module.exports.LUA_MAXINTEGER = LUA_MAXINTEGER;
const LUA_MININTEGER = -2147483648;
module.exports.LUA_MININTEGER = LUA_MININTEGER;
const luai_nummod = function(L, a, b) {
let m = a % b;
if ((m*b) < 0)
m += b;
return m;
};
module.exports.luai_nummod = luai_nummod;
// If later integers are more than 32bit, LUA_MAXINTEGER will then be != MAX_INT
const MAX_INT = 2147483647;
module.exports.MAX_INT = MAX_INT;
const MIN_INT = -2147483648;
module.exports.MIN_INT = MIN_INT;
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const lua = __webpack_require__(4);
/* key, in the registry, for table of loaded modules */
const LUA_LOADED_TABLE = "_LOADED";
/* key, in the registry, for table of preloaded loaders */
const LUA_PRELOAD_TABLE = "_PRELOAD";
const LUA_FILEHANDLE = lua.to_luastring("FILE*", true);
const LUAL_NUMSIZES = 4*16 + 8;
class luaL_Buffer {
constructor() {
this.b = null;
this.L = null;
}
}
const LEVELS1 = 10; /* size of the first part of the stack */
const LEVELS2 = 11; /* size of the second part of the stack */
/*
** search for 'objidx' in table at index -1.
** return 1 + string at top if find a good name.
*/
const findfield = function(L, objidx, level) {
if (level === 0 || !lua.lua_istable(L, -1))
return 0; /* not found */
lua.lua_pushnil(L); /* start 'next' loop */
while (lua.lua_next(L, -2)) { /* for each pair in table */
if (lua.lua_type(L, -2) === lua.LUA_TSTRING) { /* ignore non-string keys */
if (lua.lua_rawequal(L, objidx, -1)) { /* found object? */
lua.lua_pop(L, 1); /* remove value (but keep name) */
return 1;
} else if (findfield(L, objidx, level - 1)) { /* try recursively */
lua.lua_remove(L, -2); /* remove table (but keep name) */
lua.lua_pushliteral(L, ".");
lua.lua_insert(L, -2); /* place '.' between the two names */
lua.lua_concat(L, 3);
return 1;
}
}
lua.lua_pop(L, 1); /* remove value */
}
return 0; /* not found */
};
/*
** Search for a name for a function in all loaded modules
*/
const pushglobalfuncname = function(L, ar) {
let top = lua.lua_gettop(L);
lua.lua_getinfo(L, ['f'.charCodeAt(0)], ar); /* push function */
lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(LUA_LOADED_TABLE, true));
if (findfield(L, top + 1, 2)) {
let name = lua.lua_tostring(L, -1);
if (lua.to_jsstring(name).startsWith("_G.")) { /* name start with '_G.'? */
lua.lua_pushstring(L, name.slice(3)); /* push name without prefix */
lua.lua_remove(L, -2); /* remove original name */
}
lua.lua_copy(L, -1, top + 1); /* move name to proper place */
lua.lua_pop(L, 2); /* remove pushed values */
return 1;
} else {
lua.lua_settop(L, top); /* remove function and global table */
return 0;
}
};
const pushfuncname = function(L, ar) {
if (pushglobalfuncname(L, ar)) { /* try first a global name */
lua.lua_pushfstring(L, lua.to_luastring("function '%s'"), lua.lua_tostring(L, -1));
lua.lua_remove(L, -2); /* remove name */
}
else if (ar.namewhat.length !== 0) /* is there a name from code? */
lua.lua_pushfstring(L, lua.to_luastring("%s '%s'"), ar.namewhat, ar.name); /* use it */
else if (ar.what && ar.what[0] === 'm'.charCodeAt(0)) /* main? */
lua.lua_pushliteral(L, "main chunk");
else if (ar.what && ar.what[0] != 'C'.charCodeAt(0)) /* for Lua functions, use <file:line> */
lua.lua_pushfstring(L, lua.to_luastring("function <%s:%d>"), ar.short_src, ar.linedefined);
else /* nothing left... */
lua.lua_pushliteral(L, "?");
};
const lastlevel = function(L) {
let ar = new lua.lua_Debug();
let li = 1;
let le = 1;
/* find an upper bound */
while (lua.lua_getstack(L, le, ar)) { li = le; le *= 2; }
/* do a binary search */
while (li < le) {
let m = Math.floor((li + le)/2);
if (lua.lua_getstack(L, m, ar)) li = m + 1;
else le = m;
}
return le - 1;
};
const luaL_traceback = function(L, L1, msg, level) {
let ar = new lua.lua_Debug();
let top = lua.lua_gettop(L);
let last = lastlevel(L1);
let n1 = last - level > LEVELS1 + LEVELS2 ? LEVELS1 : -1;
if (msg)
lua.lua_pushfstring(L, lua.to_luastring("%s\n"), msg);
luaL_checkstack(L, 10, null);
lua.lua_pushliteral(L, "stack traceback:");
while (lua.lua_getstack(L1, level++, ar)) {
if (n1-- === 0) { /* too many levels? */
lua.lua_pushliteral(L, "\n\t..."); /* add a '...' */
level = last - LEVELS2 + 1; /* and skip to last ones */
} else {
lua.lua_getinfo(L1, lua.to_luastring("Slnt", true), ar);
lua.lua_pushfstring(L, lua.to_luastring("\n\t%s:"), ar.short_src);
if (ar.currentline > 0)
lua.lua_pushliteral(L, `${ar.currentline}:`);
lua.lua_pushliteral(L, " in ");
pushfuncname(L, ar);
if (ar.istailcall)
lua.lua_pushliteral(L, "\n\t(...tail calls..)");
lua.lua_concat(L, lua.lua_gettop(L) - top);
}
}
lua.lua_concat(L, lua.lua_gettop(L) - top);
};
const panic = function(L) {
throw new Error(`PANIC: unprotected error in call to Lua API (${lua.lua_tojsstring(L, -1)})`);
};
const luaL_argerror = function(L, arg, extramsg) {
let ar = new lua.lua_Debug();
if (!lua.lua_getstack(L, 0, ar)) /* no stack frame? */
return luaL_error(L, lua.to_luastring("bad argument #%d (%s)"), arg, extramsg);
lua.lua_getinfo(L, ['n'.charCodeAt(0)], ar);
if (lua.to_jsstring(ar.namewhat) === "method") {
arg--; /* do not count 'self' */
if (arg === 0) /* error is in the self argument itself? */
return luaL_error(L, lua.to_luastring("calling '%s' on bad self (%s)"), ar.name, extramsg);
}
if (ar.name === null)
ar.name = pushglobalfuncname(L, ar) ? lua.lua_tostring(L, -1) : ["?".charCodeAt(0)];
return luaL_error(L, lua.to_luastring("bad argument #%d to '%s' (%s)"), arg, ar.name, extramsg);
};
const typeerror = function(L, arg, tname) {
let typearg;
if (luaL_getmetafield(L, arg, lua.to_luastring("__name", true)) === lua.LUA_TSTRING)
typearg = lua.lua_tostring(L, -1);
else if (lua.lua_type(L, arg) === lua.LUA_TLIGHTUSERDATA)
typearg = lua.to_luastring("light userdata", true);
else
typearg = luaL_typename(L, arg);
let msg = lua.lua_pushfstring(L, lua.to_luastring("%s expected, got %s"), tname, typearg);
return luaL_argerror(L, arg, msg);
};
const luaL_where = function(L, level) {
let ar = new lua.lua_Debug();
if (lua.lua_getstack(L, level, ar)) {
lua.lua_getinfo(L, lua.to_luastring("Sl", true), ar);
if (ar.currentline > 0) {
lua.lua_pushfstring(L, lua.to_luastring("%s:%d: "), ar.short_src, ar.currentline);
return;
}
}
lua.lua_pushstring(L, []);
};
const luaL_error = function(L, fmt, ...argp) {
luaL_where(L, 1);
lua.lua_pushvfstring(L, fmt, argp);
lua.lua_concat(L, 2);
return lua.lua_error(L);
};
/* Unlike normal lua, we pass in an error object */
const luaL_fileresult = function(L, stat, fname, e) {
if (stat) {
lua.lua_pushboolean(L, 1);
return 1;
} else {
lua.lua_pushnil(L);
if (fname)
lua.lua_pushstring(L, lua.to_luastring(`${lua.to_jsstring(fname)}: ${e.message}`));
else
lua.lua_pushstring(L, lua.to_luastring(e.message));
lua.lua_pushinteger(L, -e.errno);
return 3;
}
};
/* Unlike normal lua, we pass in an error object */
const luaL_execresult = function(L, e) {
let what, stat;
if (e === null) {
lua.lua_pushboolean(L, 1);
lua.lua_pushliteral(L, "exit");
lua.lua_pushinteger(L, 0);
return 3;
} else if (e.status) {
what = "exit";
stat = e.status;
} else if (e.signal) {
what = "signal";
stat = e.signal;
} else {
/* XXX: node seems to have e.errno as a string instead of a number */
return luaL_fileresult(L, 0, null, e);
}
lua.lua_pushnil(L);
lua.lua_pushliteral(L, what);
lua.lua_pushinteger(L, stat);
return 3;
};
const luaL_getmetatable = function(L, n) {
return lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, n);
};
const luaL_newmetatable = function(L, tname) {
if (luaL_getmetatable(L, tname) !== lua.LUA_TNIL) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
lua.lua_pop(L, 1);
lua.lua_createtable(L, 0, 2); /* create metatable */
lua.lua_pushstring(L, tname);
lua.lua_setfield(L, -2, lua.to_luastring("__name")); /* metatable.__name = tname */
lua.lua_pushvalue(L, -1);
lua.lua_setfield(L, lua.LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
return 1;
};
const luaL_setmetatable = function(L, tname) {
luaL_getmetatable(L, tname);
lua.lua_setmetatable(L, -2);
};
const luaL_testudata = function(L, ud, tname) {
let p = lua.lua_touserdata(L, ud);
if (p !== null) { /* value is a userdata? */
if (lua.lua_getmetatable(L, ud)) { /* does it have a metatable? */
luaL_getmetatable(L, tname); /* get correct metatable */
if (!lua.lua_rawequal(L, -1, -2)) /* not the same? */
p = null; /* value is a userdata with wrong metatable */
lua.lua_pop(L, 2); /* remove both metatables */
return p;
}
}
return null; /* value is not a userdata with a metatable */
};
const luaL_checkudata = function(L, ud, tname) {
let p = luaL_testudata(L, ud, tname);
if (p === null) typeerror(L, ud, tname);
return p;
};
const luaL_checkoption = function(L, arg, def, lst) {
let name = def ? luaL_optstring(L, arg, def) : luaL_checkstring(L, arg);
for (let i = 0; lst[i]; i++)
if (lst[i].join('|') === name.join('|'))
return i;
return luaL_argerror(L, arg, lua.lua_pushfstring(L, lua.to_luastring("invalid option '%s'"), name));
};
const tag_error = function(L, arg, tag) {
typeerror(L, arg, lua.lua_typename(L, tag));
};
const luaL_newstate = function() {
let L = lua.lua_newstate();
if (L) lua.lua_atpanic(L, panic);
return L;
};
const luaL_typename = function(L, i) {
return lua.lua_typename(L, lua.lua_type(L, i));
};
const luaL_argcheck = function(L, cond, arg, extramsg) {
if (!cond) luaL_argerror(L, arg, extramsg);
};
const luaL_checkany = function(L, arg) {
if (lua.lua_type(L, arg) === lua.LUA_TNONE)
luaL_argerror(L, arg, lua.to_luastring("value expected", true));
};
const luaL_checktype = function(L, arg, t) {
if (lua.lua_type(L, arg) !== t)
tag_error(L, arg, t);
};
const luaL_checkstring = function(L, n) {
return luaL_checklstring(L, n, null);
};
const luaL_checklstring = function(L, arg) {
let s = lua.lua_tolstring(L, arg);
if (s === null || s === undefined) tag_error(L, arg, lua.LUA_TSTRING);
return s;
};
const luaL_optlstring = function(L, arg, def) {
if (lua.lua_type(L, arg) <= 0) {
return def;
} else return luaL_checklstring(L, arg);
};
const luaL_optstring = luaL_optlstring;
const interror = function(L, arg) {
if (lua.lua_isnumber(L, arg))
luaL_argerror(L, arg, lua.to_luastring("number has no integer representation", true));
else
tag_error(L, arg, lua.LUA_TNUMBER);
};
const luaL_checknumber = function(L, arg) {
let d = lua.lua_tonumberx(L, arg);
if (d === false)
tag_error(L, arg, lua.LUA_TNUMBER);
return d;
};
const luaL_optnumber = function(L, arg, def) {
return luaL_opt(L, luaL_checknumber, arg, def);
};
const luaL_checkinteger = function(L, arg) {
let d = lua.lua_tointeger(L, arg);
if (d === false)
interror(L, arg);
return d;
};
const luaL_optinteger = function(L, arg, def) {
return luaL_opt(L, luaL_checkinteger, arg, def);
};
const luaL_prepbuffsize = function(B, sz) {
return B;
};
const luaL_buffinit = function(L, B) {
B.L = L;
B.b = [];
};
const luaL_buffinitsize = function(L, B, sz) {
luaL_buffinit(L, B);
return B;
};
const LUAL_BUFFERSIZE = 8192;
const luaL_prepbuffer = function(B) {
return luaL_prepbuffsize(B, LUAL_BUFFERSIZE);
};
const luaL_addlstring = function(B, s, l) {
B.b = B.b.concat(s.slice(0, l));
};
const luaL_addstring = luaL_addlstring;
const luaL_pushresult = function(B) {
let L = B.L;
lua.lua_pushstring(L, B.b);
};
const luaL_addchar = function(B, c) {
B.b.push(c);
};
const luaL_addsize = function(B, s) {
B.n += s;
};
const luaL_pushresultsize = function(B, sz) {
luaL_addsize(B, sz);
luaL_pushresult(B);
};
const luaL_addvalue = function(B) {
let L = B.L;
let s = lua.lua_tostring(L, -1);
// TODO: buffonstack ? necessary ?
luaL_addstring(B, s);
lua.lua_remove(L, -1);
};
const luaL_opt = function(L, f, n, d) {
return lua.lua_type(L, n) <= 0 ? d : f(L, n);
};
const getS = function(L, ud) {
let s = ud.string;
ud.string = null;
return s;
};
const luaL_loadbufferx = function(L, buff, size, name, mode) {
return lua.lua_load(L, getS, {string: buff}, name, mode);
};
const luaL_loadbuffer = function(L, s, sz, n) {
return luaL_loadbufferx(L, s, sz, n, null);
};
const luaL_loadstring = function(L, s) {
return luaL_loadbuffer(L, s, s.length, s);
};
const luaL_dostring = function(L, s) {
return (luaL_loadstring(L, s) || lua.lua_pcall(L, 0, lua.LUA_MULTRET, 0));
};
const luaL_getmetafield = function(L, obj, event) {
if (!lua.lua_getmetatable(L, obj))
return lua.LUA_TNIL;
else {
lua.lua_pushstring(L, event);
let tt = lua.lua_rawget(L, -2);
if (tt === lua.LUA_TNIL)
lua.lua_pop(L, 2);
return tt;
}
};
const luaL_callmeta = function(L, obj, event) {
obj = lua.lua_absindex(L, obj);
if (luaL_getmetafield(L, obj, event) === lua.LUA_TNIL)
return false;
lua.lua_pushvalue(L, obj);
lua.lua_call(L, 1, 1);
return true;
};
const luaL_len = function(L, idx) {
lua.lua_len(L, idx);
let l = lua.lua_tointegerx(L, -1);
if (l === false)
luaL_error(L, lua.to_luastring("object length is not an integer", true));
lua.lua_pop(L, 1); /* remove object */
return l;
};
const luaL_tolstring = function(L, idx) {
if (luaL_callmeta(L, idx, lua.to_luastring("__tostring", true))) {
if (!lua.lua_isstring(L, -1))
luaL_error(L, lua.to_luastring("'__tostring' must return a string", true));
} else {
let t = lua.lua_type(L, idx);
switch(t) {
case lua.LUA_TNUMBER: {
if (lua.lua_isinteger(L, idx))
lua.lua_pushfstring(L, lua.to_luastring("%I"), lua.lua_tointeger(L, idx));
else
lua.lua_pushfstring(L, lua.to_luastring("%f"), lua.lua_tonumber(L, idx));
break;
}
case lua.LUA_TSTRING:
lua.lua_pushvalue(L, idx);
break;
case lua.LUA_TBOOLEAN:
lua.lua_pushliteral(L, (lua.lua_toboolean(L, idx) ? "true" : "false"));
break;
case lua.LUA_TNIL:
lua.lua_pushliteral(L, "nil");
break;
default:
let tt = luaL_getmetafield(L, idx, lua.to_luastring("__name", true));
let kind = tt === lua.LUA_TSTRING ? lua.lua_tostring(L, -1) : luaL_typename(L, idx);
lua.lua_pushfstring(L, lua.to_luastring("%s: %p"), kind, lua.lua_topointer(L, idx));
if (tt !== lua.LUA_TNIL)
lua.lua_remove(L, -2);
break;
}
}
return lua.lua_tolstring(L, -1);
};
/*
** Stripped-down 'require': After checking "loaded" table, calls 'openf'
** to open a module, registers the result in 'package.loaded' table and,
** if 'glb' is true, also registers the result in the global table.
** Leaves resulting module on the top.
*/
const luaL_requiref = function(L, modname, openf, glb) {
luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(LUA_LOADED_TABLE));
lua.lua_getfield(L, -1, modname); /* LOADED[modname] */
if (!lua.lua_toboolean(L, -1)) { /* package not already loaded? */
lua.lua_pop(L, 1); /* remove field */
lua.lua_pushcfunction(L, openf);
lua.lua_pushstring(L, modname); /* argument to open function */
lua.lua_call(L, 1, 1); /* call 'openf' to open module */
lua.lua_pushvalue(L, -1); /* make copy of module (call result) */
lua.lua_setfield(L, -3, modname); /* LOADED[modname] = module */
}
lua.lua_remove(L, -2); /* remove LOADED table */
if (glb) {
lua.lua_pushvalue(L, -1); /* copy of module */
lua.lua_setglobal(L, modname); /* _G[modname] = module */
}
};
const find_subarray = function(arr, subarr, from_index) {
var i = from_index >>> 0,
sl = subarr.length,
l = arr.length + 1 - sl;
loop: for (; i < l; i++) {
for (let j = 0; j < sl; j++)
if (arr[i+j] !== subarr[j])
continue loop;
return i;
}
return -1;
};
const luaL_gsub = function(L, s, p, r) {
let wild;
let b = [];
while ((wild = find_subarray(s, p)) >= 0) {
b.push(...s.slice(0, wild)); /* push prefix */
b.push(...r); /* push replacement in place of pattern */
s = s.slice(wild + p.length); /* continue after 'p' */
}
b.push(...s); /* push last suffix */
lua.lua_pushstring(L, b);
return lua.lua_tostring(L, -1);
};
/*
** ensure that stack[idx][fname] has a table and push that table
** into the stack
*/
const luaL_getsubtable = function(L, idx, fname) {
if (lua.lua_getfield(L, idx, fname) === lua.LUA_TTABLE)
return true; /* table already there */
else {
lua.lua_pop(L, 1); /* remove previous result */
idx = lua.lua_absindex(L, idx);
lua.lua_newtable(L);
lua.lua_pushvalue(L, -1); /* copy to be left at top */
lua.lua_setfield(L, idx, fname); /* assign new table to field */
return false; /* false, because did not find table there */
}
};
/*
** set functions from list 'l' into table at top - 'nup'; each
** function gets the 'nup' elements at the top as upvalues.
** Returns with only the table at the stack.
*/
const luaL_setfuncs = function(L, l, nup) {
luaL_checkstack(L, nup, lua.to_luastring("too many upvalues", true));
for (let lib in l) { /* fill the table with given functions */
for (let i = 0; i < nup; i++) /* copy upvalues to the top */
lua.lua_pushvalue(L, -nup);
lua.lua_pushcclosure(L, l[lib], nup); /* closure with those upvalues */
lua.lua_setfield(L, -(nup + 2), lua.to_luastring(lib));
}
lua.lua_pop(L, nup); /* remove upvalues */
};
/*
** Ensures the stack has at least 'space' extra slots, raising an error
** if it cannot fulfill the request. (The error handling needs a few
** extra slots to format the error message. In case of an error without
** this extra space, Lua will generate the same 'stack overflow' error,
** but without 'msg'.)
*/
const luaL_checkstack = function(L, space, msg) {
if (!lua.lua_checkstack(L, space)) {
if (msg)
luaL_error(L, lua.to_luastring("stack overflow (%s)"), msg);
else
luaL_error(L, lua.to_luastring('stack overflow', true));
}
};
const luaL_newlibtable = function(L) {
lua.lua_createtable(L);
};
const luaL_newlib = function(L, l) {
lua.lua_createtable(L);
luaL_setfuncs(L, l, 0);
};
/* predefined references */
const LUA_NOREF = -2;
const LUA_REFNIL = -1;
const luaL_ref = function(L, t) {
let ref;
if (lua.lua_isnil(L, -1)) {
lua.lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* 'nil' has a unique fixed reference */
}
t = lua.lua_absindex(L, t);
lua.lua_rawgeti(L, t, 0); /* get first free element */
ref = lua.lua_tointeger(L, -1); /* ref = t[freelist] */
lua.lua_pop(L, 1); /* remove it from stack */
if (ref !== 0) { /* any free element? */
lua.lua_rawgeti(L, t, ref); /* remove it from list */
lua.lua_rawseti(L, t, 0); /* (t[freelist] = t[ref]) */
}
else /* no free elements */
ref = lua.lua_rawlen(L, t) + 1; /* get a new reference */
lua.lua_rawseti(L, t, ref);
return ref;
};
const luaL_unref = function(L, t, ref) {
if (ref >= 0) {
t = lua.lua_absindex(L, t);
lua.lua_rawgeti(L, t, 0);
lua.lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */
lua.lua_pushinteger(L, ref);
lua.lua_rawseti(L, t, 0); /* t[freelist] = ref */
}
};
const errfile = function(L, what, fnameindex, error) {
let serr = error.message;
let filename = lua.lua_tostring(L, fnameindex).slice(1);
lua.lua_pushstring(L, lua.to_luastring(`cannot ${what} ${lua.to_jsstring(filename)}: ${serr}`));
lua.lua_remove(L, fnameindex);
return lua.LUA_ERRFILE;
};
let getc;
const utf8_bom = [0XEF, 0XBB, 0XBF]; /* UTF-8 BOM mark */
const skipBOM = function(lf) {
lf.n = 0;
let c;
let p = 0;
do {
c = getc(lf);
if (c === null || c !== utf8_bom[p]) return c;
p++;
lf.buff[lf.n++] = c; /* to be read by the parser */
} while (p < utf8_bom.length);
lf.n = 0; /* prefix matched; discard it */
return getc(lf); /* return next character */
};
/*
** reads the first character of file 'f' and skips an optional BOM mark
** in its beginning plus its first line if it starts with '#'. Returns
** true if it skipped the first line. In any case, '*cp' has the
** first "valid" character of the file (after the optional BOM and
** a first-line comment).
*/
const skipcomment = function(lf) {
let c = skipBOM(lf);
if (c === '#'.charCodeAt(0)) { /* first line is a comment (Unix exec. file)? */
do { /* skip first line */
c = getc(lf);
} while (c && c !== '\n'.charCodeAt(0));
return {
skipped: true,
c: getc(lf) /* skip end-of-line, if present */
};
} else {
return {
skipped: false,
c: c
};
}
};
let luaL_loadfilex;
class LoadF {
constructor() {
this.n = NaN; /* number of pre-read characters */
this.f = null; /* file being read */
this.buff = true ? new Array(1024) : new Buffer(1024); /* area for reading file */
this.pos = 0; /* current position in file */
this.err = void 0;
}
}
if (true) {
const getF = function(L, ud) {
let lf = ud;
if (lf.f !== null && lf.n > 0) { /* are there pre-read characters to be read? */
let bytes = lf.n; /* return them (chars already in buffer) */
lf.n = 0; /* no more pre-read characters */
lf.f = lf.f.slice(lf.pos); /* we won't use lf.buff anymore */
return lf.buff.slice(0, bytes);
}
let f = lf.f;
lf.f = null;
return f;
};
getc = function(lf) {
return lf.pos < lf.f.length ? lf.f[lf.pos++] : null;
};
luaL_loadfilex = function(L, filename, mode) {
let lf = new LoadF();
let fnameindex = lua.lua_gettop(L) + 1; /* index of filename on the stack */
if (filename === null) {
throw new Error("Can't read stdin in the browser");
} else {
lua.lua_pushfstring(L, lua.to_luastring("@%s"), filename);
let jsfilename = lua.to_jsstring(filename);
let xhr = new XMLHttpRequest();
xhr.open("GET", jsfilename, false);
// TODO: find a way to load bytes instead of js string
xhr.send();
if (xhr.status >= 200 && xhr.status <= 299) {
/* TODO: Synchronous xhr alway return a js string */
lf.f = lua.to_luastring(xhr.response);
} else {
lf.err = xhr.status;
return errfile(L, "open", fnameindex, { message: `${xhr.status}: ${xhr.statusText}` });
}
}
let com = skipcomment(lf);
/* check for signature first, as we don't want to add line number corrections in binary case */
if (com.c === lua.LUA_SIGNATURE.charCodeAt(0) && filename) { /* binary file? */
/* no need to re-open in node.js */
} else if (com.skipped) { /* read initial portion */
lf.buff[lf.n++] = '\n'.charCodeAt(0); /* add line to correct line numbers */
}
if (com.c !== null)
lf.buff[lf.n++] = com.c; /* 'c' is the first character of the stream */
let status = lua.lua_load(L, getF, lf, lua.lua_tostring(L, -1), mode);
let readstatus = lf.err;
if (readstatus) {
lua.lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
return errfile(L, "read", fnameindex, readstatus);
}
lua.lua_remove(L, fnameindex);
return status;
};
} else {
const fs = require('fs');
const getF = function(L, ud) {
let lf = ud;
let bytes = 0;
if (lf.n > 0) { /* are there pre-read characters to be read? */
bytes = lf.n; /* return them (chars already in buffer) */
lf.n = 0; /* no more pre-read characters */
} else { /* read a block from file */
lf.buff.fill(0);
try {
bytes = fs.readSync(lf.f, lf.buff, 0, lf.buff.length, lf.pos); /* read block */
} catch(e) {
lf.err = e;
bytes = 0;
}
lf.pos += bytes;
}
if (bytes > 0)
return lf.buff.slice(0, bytes); /* slice on a node.js Buffer is 'free' */
else return null;
};
getc = function(lf) {
let b = new Buffer(1);
let bytes = fs.readSync(lf.f, b, 0, 1, lf.pos);
lf.pos += bytes;
return bytes > 0 ? b.readUInt8() : null;
};
luaL_loadfilex = function(L, filename, mode) {
let lf = new LoadF();
let fnameindex = lua.lua_gettop(L) + 1; /* index of filename on the stack */
if (filename === null) {
lua.lua_pushliteral(L, "=stdin");
lf.f = process.stdin.fd;
} else {
lua.lua_pushfstring(L, lua.to_luastring("@%s"), filename);
try {
let jsfilename = lua.to_jsstring(filename);
lf.f = fs.openSync(jsfilename, "r");
if (!fs.fstatSync(lf.f).isFile())
throw new Error(`${jsfilename} is not a readable file`);
} catch (e) {
return errfile(L, "open", fnameindex, e);
}
}
let com = skipcomment(lf);
/* check for signature first, as we don't want to add line number corrections in binary case */
if (com.c === lua.LUA_SIGNATURE.charCodeAt(0) && filename) { /* binary file? */
/* no need to re-open in node.js */
} else if (com.skipped) { /* read initial portion */
lf.buff[lf.n++] = '\n'.charCodeAt(0); /* add line to correct line numbers */
}
if (com.c !== null)
lf.buff[lf.n++] = com.c; /* 'c' is the first character of the stream */
let status = lua.lua_load(L, getF, lf, lua.lua_tostring(L, -1), mode);
let readstatus = lf.err;
if (filename) try { fs.closeSync(lf.f); } catch(e) {} /* close file (even in case of errors) */
if (readstatus) {
lua.lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
return errfile(L, "read", fnameindex, readstatus);
}
lua.lua_remove(L, fnameindex);
return status;
};
}
const luaL_loadfile = function(L, filename) {
return luaL_loadfilex(L, filename, null);
};
const luaL_dofile = function(L, filename) {
return (luaL_loadfile(L, filename) || lua.lua_pcall(L, 0, lua.LUA_MULTRET, 0));
};
const lua_writestringerror = function(s) {
if (process.stderr) process.stderr.write(s);
else console.error(s);
};
const luaL_checkversion = function(L) {
let ver = lua.LUA_VERSION_NUM;
let sz = LUAL_NUMSIZES;
let v = lua.lua_version(L);
if (sz != LUAL_NUMSIZES) /* check numeric types */
luaL_error(L, lua.to_luastring("core and library have incompatible numeric types"));
if (v != lua.lua_version(null))
luaL_error(L, lua.to_luastring("multiple Lua VMs detected"));
else if (v !== ver)
luaL_error(L, lua.to_luastring("version mismatch: app. needs %f, Lua core provides %f"), ver, v);
};
module.exports.LUA_FILEHANDLE = LUA_FILEHANDLE;
module.exports.LUA_LOADED_TABLE = LUA_LOADED_TABLE;
module.exports.LUA_NOREF = LUA_NOREF;
module.exports.LUA_PRELOAD_TABLE = LUA_PRELOAD_TABLE;
module.exports.LUA_REFNIL = LUA_REFNIL;
module.exports.luaL_Buffer = luaL_Buffer;
module.exports.luaL_addchar = luaL_addchar;
module.exports.luaL_addlstring = luaL_addlstring;
module.exports.luaL_addsize = luaL_addsize;
module.exports.luaL_addstring = luaL_addstring;
module.exports.luaL_addvalue = luaL_addvalue;
module.exports.luaL_argcheck = luaL_argcheck;
module.exports.luaL_argerror = luaL_argerror;
module.exports.luaL_buffinit = luaL_buffinit;
module.exports.luaL_buffinitsize = luaL_buffinitsize;
module.exports.luaL_callmeta = luaL_callmeta;
module.exports.luaL_checkany = luaL_checkany;
module.exports.luaL_checkinteger = luaL_checkinteger;
module.exports.luaL_checklstring = luaL_checklstring;
module.exports.luaL_checknumber = luaL_checknumber;
module.exports.luaL_checkoption = luaL_checkoption;
module.exports.luaL_checkstack = luaL_checkstack;
module.exports.luaL_checkstring = luaL_checkstring;
module.exports.luaL_checktype = luaL_checktype;
module.exports.luaL_checkudata = luaL_checkudata;
module.exports.luaL_checkversion = luaL_checkversion;
module.exports.luaL_dofile = luaL_dofile;
module.exports.luaL_dostring = luaL_dostring;
module.exports.luaL_error = luaL_error;
module.exports.luaL_execresult = luaL_execresult;
module.exports.luaL_fileresult = luaL_fileresult;
module.exports.luaL_getmetafield = luaL_getmetafield;
module.exports.luaL_getmetatable = luaL_getmetatable;
module.exports.luaL_getsubtable = luaL_getsubtable;
module.exports.luaL_gsub = luaL_gsub;
module.exports.luaL_len = luaL_len;
module.exports.luaL_loadbuffer = luaL_loadbuffer;
module.exports.luaL_loadbufferx = luaL_loadbufferx;
module.exports.luaL_loadfile = luaL_loadfile;
module.exports.luaL_loadfilex = luaL_loadfilex;
module.exports.luaL_loadstring = luaL_loadstring;
module.exports.luaL_newlib = luaL_newlib;
module.exports.luaL_newlibtable = luaL_newlibtable;
module.exports.luaL_newmetatable = luaL_newmetatable;
module.exports.luaL_newstate = luaL_newstate;
module.exports.luaL_opt = luaL_opt;
module.exports.luaL_optinteger = luaL_optinteger;
module.exports.luaL_optlstring = luaL_optlstring;
module.exports.luaL_optnumber = luaL_optnumber;
module.exports.luaL_optstring = luaL_optstring;
module.exports.luaL_prepbuffer = luaL_prepbuffer;
module.exports.luaL_prepbuffsize = luaL_prepbuffsize;
module.exports.luaL_pushresult = luaL_pushresult;
module.exports.luaL_pushresultsize = luaL_pushresultsize;
module.exports.luaL_ref = luaL_ref;
module.exports.luaL_requiref = luaL_requiref;
module.exports.luaL_setfuncs = luaL_setfuncs;
module.exports.luaL_setmetatable = luaL_setmetatable;
module.exports.luaL_testudata = luaL_testudata;
module.exports.luaL_tolstring = luaL_tolstring;
module.exports.luaL_traceback = luaL_traceback;
module.exports.luaL_typename = luaL_typename;
module.exports.luaL_unref = luaL_unref;
module.exports.luaL_where = luaL_where;
module.exports.lua_writestringerror = lua_writestringerror;
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const lapi = __webpack_require__(37);
const ldebug = __webpack_require__(19);
const lfunc = __webpack_require__(20);
const llimit = __webpack_require__(8);
const lobject = __webpack_require__(5);
const lopcodes= __webpack_require__(28);
const lparser = __webpack_require__(41);
const lstate = __webpack_require__(21);
const lstring = __webpack_require__(15);
const ltm = __webpack_require__(26);
const luaconf = __webpack_require__(18);
const lundump = __webpack_require__(71);
const lvm = __webpack_require__(27);
const lzio = __webpack_require__(35);
const CT = defs.constant_types;
const TS = defs.thread_status;
const adjust_top = function(L, newtop) {
if (L.top < newtop) {
while (L.top < newtop)
L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null);
} else {
while (L.top > newtop)
delete L.stack[--L.top];
}
};
const seterrorobj = function(L, errcode, oldtop) {
let current_top = L.top;
/* extend stack so that L.stack[oldtop] is sure to exist */
while (L.top < oldtop + 1)
L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null);
switch (errcode) {
case TS.LUA_ERRMEM: {
lobject.setsvalue2s(L, oldtop, lstring.luaS_newliteral(L, "not enough memory"));
break;
}
case TS.LUA_ERRERR: {
lobject.setsvalue2s(L, oldtop, lstring.luaS_newliteral(L, "error in error handling"));
break;
}
default: {
lobject.setobjs2s(L, oldtop, current_top - 1);
}
}
while (L.top > oldtop + 1)
delete L.stack[--L.top];
};
const ERRORSTACKSIZE = luaconf.LUAI_MAXSTACK + 200;
const luaD_reallocstack = function(L, newsize) {
assert(newsize <= luaconf.LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
assert(L.stack_last == L.stack.length - lstate.EXTRA_STACK);
L.stack.length = newsize;
L.stack_last = newsize - lstate.EXTRA_STACK;
};
const luaD_growstack = function(L, n) {
let size = L.stack.length;
if (size > luaconf.LUAI_MAXSTACK)
luaD_throw(L, TS.LUA_ERRERR);
else {
let needed = L.top + n + lstate.EXTRA_STACK;
let newsize = 2 * size;
if (newsize > luaconf.LUAI_MAXSTACK) newsize = luaconf.LUAI_MAXSTACK;
if (newsize < needed) newsize = needed;
if (newsize > luaconf.LUAI_MAXSTACK) { /* stack overflow? */
luaD_reallocstack(L, ERRORSTACKSIZE);
ldebug.luaG_runerror(L, defs.to_luastring("stack overflow", true));
}
else
luaD_reallocstack(L, newsize);
}
};
const luaD_checkstack = function(L, n) {
if (L.stack_last - L.top <= n)
luaD_growstack(L, n);
};
const stackinuse = function(L) {
let lim = L.top;
for (let ci = L.ci; ci !== null; ci = ci.previous) {
if (lim < ci.top) lim = ci.top;
}
assert(lim <= L.stack_last);
return lim + 1; /* part of stack in use */
};
const luaD_shrinkstack = function(L) {
let inuse = stackinuse(L);
let goodsize = inuse + Math.floor(inuse / 8) + 2*lstate.EXTRA_STACK;
if (goodsize > luaconf.LUAI_MAXSTACK)
goodsize = luaconf.LUAI_MAXSTACK; /* respect stack limit */
if (L.stack.length > luaconf.LUAI_MAXSTACK) /* had been handling stack overflow? */
lstate.luaE_freeCI(L); /* free all CIs (list grew because of an error) */
/* if thread is currently not handling a stack overflow and its
good size is smaller than current size, shrink its stack */
if (inuse <= (luaconf.LUAI_MAXSTACK - lstate.EXTRA_STACK) && goodsize < L.stack.length)
luaD_reallocstack(L, goodsize);
};
const luaD_inctop = function(L) {
luaD_checkstack(L, 1);
L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null);
};
/*
** Prepares a function call: checks the stack, creates a new CallInfo
** entry, fills in the relevant information, calls hook if needed.
** If function is a JS function, does the call, too. (Otherwise, leave
** the execution ('luaV_execute') to the caller, to allow stackless
** calls.) Returns true iff function has been executed (JS function).
*/
const luaD_precall = function(L, off, nresults) {
let func = L.stack[off];
switch(func.type) {
case CT.LUA_TCCL:
case CT.LUA_TLCF: {
let f = func.type === CT.LUA_TCCL ? func.value.f : func.value;
luaD_checkstack(L, defs.LUA_MINSTACK);
let ci = lstate.luaE_extendCI(L);
ci.funcOff = off;
ci.nresults = nresults;
ci.func = func;
ci.top = L.top + defs.LUA_MINSTACK;
assert(ci.top <= L.stack_last);
ci.callstatus = 0;
if (L.hookmask & defs.LUA_MASKCALL)
luaD_hook(L, defs.LUA_HOOKCALL, -1);
let n = f(L); /* do the actual call */
assert(typeof n == "number" && n >= 0 && (n|0) === n, "invalid return value from JS function (expected integer)");
assert(n < L.top - L.ci.funcOff, "not enough elements in the stack");
luaD_poscall(L, ci, L.top - n, n);
return true;
}
case CT.LUA_TLCL: {
let base;
let p = func.value.p;
let n = L.top - off - 1;
let fsize = p.maxstacksize;
luaD_checkstack(L, fsize);
if (p.is_vararg) {
base = adjust_varargs(L, p, n);
} else {
for (; n < p.numparams; n++)
L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); // complete missing arguments
base = off + 1;
}
let ci = lstate.luaE_extendCI(L);
ci.funcOff = off;
ci.nresults = nresults;
ci.func = func;
ci.l_base = base;
ci.top = base + fsize;
adjust_top(L, ci.top);
ci.l_code = p.code;
ci.l_savedpc = 0;
ci.callstatus = lstate.CIST_LUA;
if (L.hookmask & defs.LUA_MASKCALL)
callhook(L, ci);
return false;
}
default:
luaD_checkstack(L, 1);
tryfuncTM(L, off, func);
return luaD_precall(L, off, nresults);
}
};
const luaD_poscall = function(L, ci, firstResult, nres) {
let wanted = ci.nresults;
if (L.hookmask & (defs.LUA_MASKRET | defs.LUA_MASKLINE)) {
if (L.hookmask & defs.LUA_MASKRET)
luaD_hook(L, defs.LUA_HOOKRET, -1);
L.oldpc = ci.previous.l_savedpc; /* 'oldpc' for caller function */
}
let res = ci.funcOff;
L.ci = ci.previous;
L.ci.next = null;
return moveresults(L, firstResult, res, nres, wanted);
};
const moveresults = function(L, firstResult, res, nres, wanted) {
switch (wanted) {
case 0:
break;
case 1: {
if (nres === 0)
L.stack[res].setnilvalue();
else {
lobject.setobjs2s(L, res, firstResult); /* move it to proper place */
}
break;
}
case defs.LUA_MULTRET: {
for (let i = 0; i < nres; i++)
lobject.setobjs2s(L, res + i, firstResult + i);
for (let i=L.top; i>=(res + nres); i--)
delete L.stack[i];
L.top = res + nres;
return false;
}
default: {
let i;
if (wanted <= nres) {
for (i = 0; i < wanted; i++)
lobject.setobjs2s(L, res + i, firstResult + i);
} else {
for (i = 0; i < nres; i++)
lobject.setobjs2s(L, res + i, firstResult + i);
for (; i < wanted; i++) {
if (res+i >= L.top)
L.stack[res + i] = new lobject.TValue(CT.LUAT_NIL, null);
else
L.stack[res + i].setnilvalue();
}
}
break;
}
}
let newtop = res + wanted; /* top points after the last result */
for (let i=L.top; i>=newtop; i--)
delete L.stack[i];
L.top = newtop;
return true;
};
/*
** Call a hook for the given event. Make sure there is a hook to be
** called. (Both 'L->hook' and 'L->hookmask', which triggers this
** function, can be changed asynchronously by signals.)
*/
const luaD_hook = function(L, event, line) {
let hook = L.hook;
if (hook && L.allowhook) { /* make sure there is a hook */
let ci = L.ci;
let top = L.top;
let ci_top = ci.top;
let ar = new defs.lua_Debug();
ar.event = event;
ar.currentline = line;
ar.i_ci = ci;
luaD_checkstack(L, defs.LUA_MINSTACK); /* ensure minimum stack size */
ci.top = L.top + defs.LUA_MINSTACK;
assert(ci.top <= L.stack_last);
L.allowhook = 0; /* cannot call hooks inside a hook */
ci.callstatus |= lstate.CIST_HOOKED;
hook(L, ar);
assert(!L.allowhook);
L.allowhook = 1;
ci.top = ci_top;
adjust_top(L, top);
ci.callstatus &= ~lstate.CIST_HOOKED;
}
};
const callhook = function(L, ci) {
let hook = defs.LUA_HOOKCALL;
ci.l_savedpc++; /* hooks assume 'pc' is already incremented */
if ((ci.previous.callstatus & lstate.CIST_LUA) &&
ci.previous.l_code[ci.previous.l_savedpc - 1].opcode == lopcodes.OpCodesI.OP_TAILCALL) {
ci.callstatus |= lstate.CIST_TAIL;
hook = defs.LUA_HOOKTAILCALL;
}
luaD_hook(L, hook, -1);
ci.l_savedpc--; /* correct 'pc' */
};
const adjust_varargs = function(L, p, actual) {
let nfixargs = p.numparams;
/* move fixed parameters to final position */
let fixed = L.top - actual; /* first fixed argument */
let base = L.top; /* final position of first argument */
let i;
for (i = 0; i < nfixargs && i < actual; i++) {
lobject.pushobj2s(L, L.stack[fixed + i]);
L.stack[fixed + i].setnilvalue();
}
for (; i < nfixargs; i++)
L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null);
return base;
};
const tryfuncTM = function(L, off, func) {
let tm = ltm.luaT_gettmbyobj(L, func, ltm.TMS.TM_CALL);
if (!tm.ttisfunction(tm))
ldebug.luaG_typeerror(L, func, defs.to_luastring("call", true));
/* Open a hole inside the stack at 'func' */
lobject.pushobj2s(L, L.stack[L.top-1]); /* push top of stack again */
for (let p = L.top-2; p > off; p--)
lobject.setobjs2s(L, p, p-1); /* move other items up one */
lobject.setobj2s(L, off, tm); /* tag method is the new function to be called */
};
/*
** Check appropriate error for stack overflow ("regular" overflow or
** overflow while handling stack overflow). If 'nCalls' is larger than
** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but
** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to
** allow overflow handling to work)
*/
const stackerror = function(L) {
if (L.nCcalls === llimit.LUAI_MAXCCALLS)
ldebug.luaG_runerror(L, defs.to_luastring("JS stack overflow", true));
else if (L.nCcalls >= llimit.LUAI_MAXCCALLS + (llimit.LUAI_MAXCCALLS >> 3))
luaD_throw(L, TS.LUA_ERRERR); /* error while handing stack error */
};
/*
** Call a function (JS or Lua). The function to be called is at func.
** The arguments are on the stack, right after the function.
** When returns, all the results are on the stack, starting at the original
** function position.
*/
const luaD_call = function(L, off, nResults) {
if (++L.nCcalls >= llimit.LUAI_MAXCCALLS)
stackerror(L);
if (!luaD_precall(L, off, nResults))
lvm.luaV_execute(L);
L.nCcalls--;
};
const luaD_throw = function(L, errcode) {
if (L.errorJmp) { /* thread has an error handler? */
L.errorJmp.status = errcode; /* set status */
throw L.errorJmp;
} else { /* thread has no error handler */
let g = L.l_G;
L.status = errcode; /* mark it as dead */
if (g.mainthread.errorJmp) { /* main thread has a handler? */
g.mainthread.stack[g.mainthread.top++] = L.stack[L.top - 1]; /* copy error obj. */
luaD_throw(g.mainthread, errcode); /* re-throw in main thread */
} else { /* no handler at all; abort */
let panic = g.panic;
if (panic) { /* panic function? */
seterrorobj(L, errcode, L.top); /* assume EXTRA_STACK */
if (L.ci.top < L.top)
L.ci.top = L.top; /* pushing msg. can break this invariant */
panic(L); /* call panic function (last chance to jump out) */
}
throw new Error(`Aborted ${errcode}`);
}
}
};
const luaD_rawrunprotected = function(L, f, ud) {
let oldnCcalls = L.nCcalls;
let lj = { // TODO: necessary when using try/catch ? (ldo.c:47-52)
status: TS.LUA_OK,
previous: L.errorJmp /* chain new error handler */
};
L.errorJmp = lj;
try {
f(L, ud);
} catch (e) {
if (lj.status === TS.LUA_OK) {
/* error was not thrown via luaD_throw, i.e. it is a JS error */
/* run user error handler (if it exists) */
let atnativeerror = L.l_G.atnativeerror;
if (atnativeerror) {
try {
lj.status = TS.LUA_OK;
lapi.lua_pushcfunction(L, atnativeerror);
lapi.lua_pushlightuserdata(L, e);
luaD_callnoyield(L, L.top - 2, 1);
/* Now run the message handler (if it exists) */
/* copy of luaG_errormsg without the throw */
if (L.errfunc !== 0) { /* is there an error handling function? */
let errfunc = L.errfunc;
lobject.pushobj2s(L, L.stack[L.top - 1]); /* move argument */
lobject.setobjs2s(L, L.top - 2, errfunc); /* push function */
luaD_callnoyield(L, L.top - 2, 1);
}
lj.status = TS.LUA_ERRRUN;
} catch(e2) {
if (lj.status === TS.LUA_OK) {
/* also failed */
lj.status = -1;
}
}
} else {
lj.status = -1;
}
}
}
L.errorJmp = lj.previous;
L.nCcalls = oldnCcalls;
return lj.status;
};
/*
** Completes the execution of an interrupted C function, calling its
** continuation function.
*/
const finishCcall = function(L, status) {
let ci = L.ci;
/* must have a continuation and must be able to call it */
assert(ci.c_k !== null && L.nny === 0);
/* error status can only happen in a protected call */
assert(ci.callstatus & lstate.CIST_YPCALL || status === TS.LUA_YIELD);
if (ci.callstatus & TS.CIST_YPCALL) { /* was inside a pcall? */
ci.callstatus &= ~TS.CIST_YPCALL; /* continuation is also inside it */
L.errfunc = ci.c_old_errfunc; /* with the same error function */
}
/* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
handled */
if (ci.nresults === defs.LUA_MULTRET && L.ci.top < L.top) L.ci.top = L.top;
let c_k = ci.c_k; /* don't want to call as method */
let n = c_k(L, status, ci.c_ctx); /* call continuation function */
assert(n < (L.top - L.ci.funcOff), "not enough elements in the stack");
luaD_poscall(L, ci, L.top - n, n); /* finish 'luaD_precall' */
};
/*
** Executes "full continuation" (everything in the stack) of a
** previously interrupted coroutine until the stack is empty (or another
** interruption long-jumps out of the loop). If the coroutine is
** recovering from an error, 'ud' points to the error status, which must
** be passed to the first continuation function (otherwise the default
** status is LUA_YIELD).
*/
const unroll = function(L, ud) {
if (ud !== null) /* error status? */
finishCcall(L, ud); /* finish 'lua_pcallk' callee */
while (L.ci !== L.base_ci) { /* something in the stack */
if (!(L.ci.callstatus & lstate.CIST_LUA)) /* C function? */
finishCcall(L, TS.LUA_YIELD); /* complete its execution */
else { /* Lua function */
lvm.luaV_finishOp(L); /* finish interrupted instruction */
lvm.luaV_execute(L); /* execute down to higher C 'boundary' */
}
}
};
/*
** Try to find a suspended protected call (a "recover point") for the
** given thread.
*/
const findpcall = function(L) {
for (let ci = L.ci; ci !== null; ci = ci.previous) { /* search for a pcall */
if (ci.callstatus & lstate.CIST_YPCALL)
return ci;
}
return null; /* no pending pcall */
};
/*
** Recovers from an error in a coroutine. Finds a recover point (if
** there is one) and completes the execution of the interrupted
** 'luaD_pcall'. If there is no recover point, returns zero.
*/
const recover = function(L, status) {
let ci = findpcall(L);
if (ci === null) return 0; /* no recovery point */
/* "finish" luaD_pcall */
let oldtop = ci.extra;
lfunc.luaF_close(L, oldtop);
seterrorobj(L, status, oldtop);
L.ci = ci;
L.allowhook = ci.callstatus & lstate.CIST_OAH; /* restore original 'allowhook' */
L.nny = 0; /* should be zero to be yieldable */
luaD_shrinkstack(L);
L.errfunc = ci.c_old_errfunc;
return 1; /* continue running the coroutine */
};
/*
** Signal an error in the call to 'lua_resume', not in the execution
** of the coroutine itself. (Such errors should not be handled by any
** coroutine error handler and should not kill the coroutine.)
*/
const resume_error = function(L, msg, narg) {
let ts = lstring.luaS_newliteral(L, msg);
if (narg === 0) {
lobject.pushsvalue2s(L, ts);
assert(L.top <= L.ci.top, "stack overflow");
} else {
/* remove args from the stack */
for (let i=1; i<narg; i++)
delete L.stack[--L.top];
lobject.setsvalue2s(L, L.top-1, ts); /* push error message */
}
return TS.LUA_ERRRUN;
};
/*
** Do the work for 'lua_resume' in protected mode. Most of the work
** depends on the status of the coroutine: initial state, suspended
** inside a hook, or regularly suspended (optionally with a continuation
** function), plus erroneous cases: non-suspended coroutine or dead
** coroutine.
*/
const resume = function(L, n) {
let firstArg = L.top - n; /* first argument */
let ci = L.ci;
if (L.status === TS.LUA_OK) { /* starting a coroutine? */
if (!luaD_precall(L, firstArg - 1, defs.LUA_MULTRET)) /* Lua function? */
lvm.luaV_execute(L); /* call it */
} else { /* resuming from previous yield */
assert(L.status === TS.LUA_YIELD);
L.status = TS.LUA_OK; /* mark that it is running (again) */
ci.funcOff = ci.extra;
ci.func = L.stack[ci.funcOff];
if (ci.callstatus & lstate.CIST_LUA) /* yielded inside a hook? */
lvm.luaV_execute(L); /* just continue running Lua code */
else { /* 'common' yield */
if (ci.c_k !== null) { /* does it have a continuation function? */
n = ci.c_k(L, TS.LUA_YIELD, ci.c_ctx); /* call continuation */
assert(n < (L.top - L.ci.funcOff), "not enough elements in the stack");
firstArg = L.top - n; /* yield results come from continuation */
}
luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */
}
unroll(L, null); /* run continuation */
}
};
const lua_resume = function(L, from, nargs) {
let oldnny = L.nny; /* save "number of non-yieldable" calls */
if (L.status === TS.LUA_OK) { /* may be starting a coroutine */
if (L.ci !== L.base_ci) /* not in base level? */
return resume_error(L, "cannot resume non-suspended coroutine", nargs);
} else if (L.status !== TS.LUA_YIELD)
return resume_error(L, "cannot resume dead coroutine", nargs);
L.nCcalls = from ? from.nCcalls + 1 : 1;
if (L.nCcalls >= llimit.LUAI_MAXCCALLS)
return resume_error(L, "JS stack overflow", nargs);
L.nny = 0; /* allow yields */
assert((L.status === TS.LUA_OK ? nargs + 1: nargs) < (L.top - L.ci.funcOff),
"not enough elements in the stack");
let status = luaD_rawrunprotected(L, resume, nargs);
if (status === -1) /* error calling 'lua_resume'? */
status = TS.LUA_ERRRUN;
else { /* continue running after recoverable errors */
while (status > TS.LUA_YIELD && recover(L, status)) {
/* unroll continuation */
status = luaD_rawrunprotected(L, unroll, status);
}
if (status > TS.LUA_YIELD) { /* unrecoverable error? */
L.status = status; /* mark thread as 'dead' */
seterrorobj(L, status, L.top); /* push error message */
L.ci.top = L.top;
} else
assert(status === L.status); /* normal end or yield */
}
L.nny = oldnny; /* restore 'nny' */
L.nCcalls--;
assert(L.nCcalls === (from ? from.nCcalls : 0));
return status;
};
const lua_isyieldable = function(L) {
return L.nny === 0;
};
const lua_yieldk = function(L, nresults, ctx, k) {
let ci = L.ci;
assert(nresults < (L.top - L.ci.funcOff), "not enough elements in the stack");
if (L.nny > 0) {
if (L !== L.l_G.mainthread)
ldebug.luaG_runerror(L, defs.to_luastring("attempt to yield across a JS-call boundary", true));
else
ldebug.luaG_runerror(L, defs.to_luastring("attempt to yield from outside a coroutine", true));
}
L.status = TS.LUA_YIELD;
ci.extra = ci.funcOff; /* save current 'func' */
if (ci.callstatus & lstate.CIST_LUA) /* inside a hook? */
assert(k === null, "hooks cannot continue after yielding");
else {
ci.c_k = k;
if (k !== null) /* is there a continuation? */
ci.c_ctx = ctx; /* save context */
ci.funcOff = L.top - nresults - 1; /* protect stack below results */
ci.func = L.stack[ci.funcOff];
luaD_throw(L, TS.LUA_YIELD);
}
assert(ci.callstatus & lstate.CIST_HOOKED); /* must be inside a hook */
return 0; /* return to 'luaD_hook' */
};
const lua_yield = function(L, n) {
lua_yieldk(L, n, 0, null);
};
const luaD_pcall = function(L, func, u, old_top, ef) {
let old_ci = L.ci;
let old_allowhooks = L.allowhook;
let old_nny = L.nny;
let old_errfunc = L.errfunc;
L.errfunc = ef;
let status = luaD_rawrunprotected(L, func, u);
if (status !== TS.LUA_OK) {
lfunc.luaF_close(L, old_top);
seterrorobj(L, status, old_top);
L.ci = old_ci;
L.allowhook = old_allowhooks;
L.nny = old_nny;
luaD_shrinkstack(L);
}
L.errfunc = old_errfunc;
return status;
};
/*
** Similar to 'luaD_call', but does not allow yields during the call
*/
const luaD_callnoyield = function(L, off, nResults) {
L.nny++;
luaD_call(L, off, nResults);
L.nny--;
};
/*
** Execute a protected parser.
*/
class SParser {
constructor(z, name, mode) { /* data to 'f_parser' */
this.z = z;
this.buff = new lzio.MBuffer(); /* dynamic structure used by the scanner */
this.dyd = new lparser.Dyndata(); /* dynamic structures used by the parser */
this.mode = mode;
this.name = name;
}
}
const checkmode = function(L, mode, x) {
if (mode && mode.indexOf(x[0]) === -1) {
lapi.lua_pushstring(L, defs.to_luastring(`attempt to load a ${defs.to_jsstring(x)} chunk (mode is '${defs.to_jsstring(mode)}')`));
luaD_throw(L, TS.LUA_ERRSYNTAX);
}
};
const f_parser = function(L, p) {
let cl;
let c = p.z.zgetc(); /* read first character */
if (c === defs.LUA_SIGNATURE.charCodeAt(0)) {
checkmode(L, p.mode, defs.to_luastring("binary", true));
cl = lundump.luaU_undump(L, p.z, p.name);
} else {
checkmode(L, p.mode, defs.to_luastring("text", true));
cl = lparser.luaY_parser(L, p.z, p.buff, p.dyd, p.name, c);
}
assert(cl.nupvalues === cl.p.upvalues.length);
lfunc.luaF_initupvals(L, cl);
};
const luaD_protectedparser = function(L, z, name, mode) {
let p = new SParser(z, name, mode);
L.nny++; /* cannot yield during parsing */
let status = luaD_pcall(L, f_parser, p, L.top, L.errfunc);
L.nny--;
return status;
};
module.exports.adjust_top = adjust_top;
module.exports.luaD_call = luaD_call;
module.exports.luaD_callnoyield = luaD_callnoyield;
module.exports.luaD_checkstack = luaD_checkstack;
module.exports.luaD_growstack = luaD_growstack;
module.exports.luaD_hook = luaD_hook;
module.exports.luaD_inctop = luaD_inctop;
module.exports.luaD_pcall = luaD_pcall;
module.exports.luaD_poscall = luaD_poscall;
module.exports.luaD_precall = luaD_precall;
module.exports.luaD_protectedparser = luaD_protectedparser;
module.exports.luaD_rawrunprotected = luaD_rawrunprotected;
module.exports.luaD_reallocstack = luaD_reallocstack;
module.exports.luaD_throw = luaD_throw;
module.exports.lua_isyieldable = lua_isyieldable;
module.exports.lua_resume = lua_resume;
module.exports.lua_yield = lua_yield;
module.exports.lua_yieldk = lua_yieldk;
/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const lapi = __webpack_require__(38);
const ldebug = __webpack_require__(23);
const lfunc = __webpack_require__(24);
const llimit = __webpack_require__(10);
const lobject = __webpack_require__(7);
const lopcodes= __webpack_require__(33);
const lparser = __webpack_require__(55);
const lstate = __webpack_require__(25);
const lstring = __webpack_require__(17);
const ltm = __webpack_require__(31);
const luaconf = __webpack_require__(22);
const lundump = __webpack_require__(86);
const lvm = __webpack_require__(32);
const lzio = __webpack_require__(36);
const CT = defs.constant_types;
const TS = defs.thread_status;
const adjust_top = function(L, newtop) {
if (L.top < newtop) {
while (L.top < newtop)
L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null);
} else {
while (L.top > newtop)
delete L.stack[--L.top];
}
};
const seterrorobj = function(L, errcode, oldtop) {
let current_top = L.top;
/* extend stack so that L.stack[oldtop] is sure to exist */
while (L.top < oldtop + 1)
L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null);
switch (errcode) {
case TS.LUA_ERRMEM: {
lobject.setsvalue2s(L, oldtop, lstring.luaS_newliteral(L, "not enough memory"));
break;
}
case TS.LUA_ERRERR: {
lobject.setsvalue2s(L, oldtop, lstring.luaS_newliteral(L, "error in error handling"));
break;
}
default: {
lobject.setobjs2s(L, oldtop, current_top - 1);
}
}
while (L.top > oldtop + 1)
delete L.stack[--L.top];
};
const ERRORSTACKSIZE = luaconf.LUAI_MAXSTACK + 200;
const luaD_reallocstack = function(L, newsize) {
assert(newsize <= luaconf.LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
assert(L.stack_last == L.stack.length - lstate.EXTRA_STACK);
L.stack.length = newsize;
L.stack_last = newsize - lstate.EXTRA_STACK;
};
const luaD_growstack = function(L, n) {
let size = L.stack.length;
if (size > luaconf.LUAI_MAXSTACK)
luaD_throw(L, TS.LUA_ERRERR);
else {
let needed = L.top + n + lstate.EXTRA_STACK;
let newsize = 2 * size;
if (newsize > luaconf.LUAI_MAXSTACK) newsize = luaconf.LUAI_MAXSTACK;
if (newsize < needed) newsize = needed;
if (newsize > luaconf.LUAI_MAXSTACK) { /* stack overflow? */
luaD_reallocstack(L, ERRORSTACKSIZE);
ldebug.luaG_runerror(L, defs.to_luastring("stack overflow", true));
}
else
luaD_reallocstack(L, newsize);
}
};
const luaD_checkstack = function(L, n) {
if (L.stack_last - L.top <= n)
luaD_growstack(L, n);
};
const stackinuse = function(L) {
let lim = L.top;
for (let ci = L.ci; ci !== null; ci = ci.previous) {
if (lim < ci.top) lim = ci.top;
}
assert(lim <= L.stack_last);
return lim + 1; /* part of stack in use */
};
const luaD_shrinkstack = function(L) {
let inuse = stackinuse(L);
let goodsize = inuse + Math.floor(inuse / 8) + 2*lstate.EXTRA_STACK;
if (goodsize > luaconf.LUAI_MAXSTACK)
goodsize = luaconf.LUAI_MAXSTACK; /* respect stack limit */
if (L.stack.length > luaconf.LUAI_MAXSTACK) /* had been handling stack overflow? */
lstate.luaE_freeCI(L); /* free all CIs (list grew because of an error) */
/* if thread is currently not handling a stack overflow and its
good size is smaller than current size, shrink its stack */
if (inuse <= (luaconf.LUAI_MAXSTACK - lstate.EXTRA_STACK) && goodsize < L.stack.length)
luaD_reallocstack(L, goodsize);
};
const luaD_inctop = function(L) {
luaD_checkstack(L, 1);
L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null);
};
/*
** Prepares a function call: checks the stack, creates a new CallInfo
** entry, fills in the relevant information, calls hook if needed.
** If function is a JS function, does the call, too. (Otherwise, leave
** the execution ('luaV_execute') to the caller, to allow stackless
** calls.) Returns true iff function has been executed (JS function).
*/
const luaD_precall = function(L, off, nresults) {
let func = L.stack[off];
switch(func.type) {
case CT.LUA_TCCL:
case CT.LUA_TLCF: {
let f = func.type === CT.LUA_TCCL ? func.value.f : func.value;
luaD_checkstack(L, defs.LUA_MINSTACK);
let ci = lstate.luaE_extendCI(L);
ci.funcOff = off;
ci.nresults = nresults;
ci.func = func;
ci.top = L.top + defs.LUA_MINSTACK;
assert(ci.top <= L.stack_last);
ci.callstatus = 0;
if (L.hookmask & defs.LUA_MASKCALL)
luaD_hook(L, defs.LUA_HOOKCALL, -1);
let n = f(L); /* do the actual call */
assert(typeof n == "number" && n >= 0 && (n|0) === n, "invalid return value from JS function (expected integer)");
assert(n < L.top - L.ci.funcOff, "not enough elements in the stack");
luaD_poscall(L, ci, L.top - n, n);
return true;
}
case CT.LUA_TLCL: {
let base;
let p = func.value.p;
let n = L.top - off - 1;
let fsize = p.maxstacksize;
luaD_checkstack(L, fsize);
if (p.is_vararg) {
base = adjust_varargs(L, p, n);
} else {
for (; n < p.numparams; n++)
L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null); // complete missing arguments
base = off + 1;
}
let ci = lstate.luaE_extendCI(L);
ci.funcOff = off;
ci.nresults = nresults;
ci.func = func;
ci.l_base = base;
ci.top = base + fsize;
adjust_top(L, ci.top);
ci.l_code = p.code;
ci.l_savedpc = 0;
ci.callstatus = lstate.CIST_LUA;
if (L.hookmask & defs.LUA_MASKCALL)
callhook(L, ci);
return false;
}
default:
luaD_checkstack(L, 1);
tryfuncTM(L, off, func);
return luaD_precall(L, off, nresults);
}
};
const luaD_poscall = function(L, ci, firstResult, nres) {
let wanted = ci.nresults;
if (L.hookmask & (defs.LUA_MASKRET | defs.LUA_MASKLINE)) {
if (L.hookmask & defs.LUA_MASKRET)
luaD_hook(L, defs.LUA_HOOKRET, -1);
L.oldpc = ci.previous.l_savedpc; /* 'oldpc' for caller function */
}
let res = ci.funcOff;
L.ci = ci.previous;
L.ci.next = null;
return moveresults(L, firstResult, res, nres, wanted);
};
const moveresults = function(L, firstResult, res, nres, wanted) {
switch (wanted) {
case 0:
break;
case 1: {
if (nres === 0)
L.stack[res].setnilvalue();
else {
lobject.setobjs2s(L, res, firstResult); /* move it to proper place */
}
break;
}
case defs.LUA_MULTRET: {
for (let i = 0; i < nres; i++)
lobject.setobjs2s(L, res + i, firstResult + i);
for (let i=L.top; i>=(res + nres); i--)
delete L.stack[i];
L.top = res + nres;
return false;
}
default: {
let i;
if (wanted <= nres) {
for (i = 0; i < wanted; i++)
lobject.setobjs2s(L, res + i, firstResult + i);
} else {
for (i = 0; i < nres; i++)
lobject.setobjs2s(L, res + i, firstResult + i);
for (; i < wanted; i++) {
if (res+i >= L.top)
L.stack[res + i] = new lobject.TValue(CT.LUAT_NIL, null);
else
L.stack[res + i].setnilvalue();
}
}
break;
}
}
let newtop = res + wanted; /* top points after the last result */
for (let i=L.top; i>=newtop; i--)
delete L.stack[i];
L.top = newtop;
return true;
};
/*
** Call a hook for the given event. Make sure there is a hook to be
** called. (Both 'L->hook' and 'L->hookmask', which triggers this
** function, can be changed asynchronously by signals.)
*/
const luaD_hook = function(L, event, line) {
let hook = L.hook;
if (hook && L.allowhook) { /* make sure there is a hook */
let ci = L.ci;
let top = L.top;
let ci_top = ci.top;
let ar = new defs.lua_Debug();
ar.event = event;
ar.currentline = line;
ar.i_ci = ci;
luaD_checkstack(L, defs.LUA_MINSTACK); /* ensure minimum stack size */
ci.top = L.top + defs.LUA_MINSTACK;
assert(ci.top <= L.stack_last);
L.allowhook = 0; /* cannot call hooks inside a hook */
ci.callstatus |= lstate.CIST_HOOKED;
hook(L, ar);
assert(!L.allowhook);
L.allowhook = 1;
ci.top = ci_top;
adjust_top(L, top);
ci.callstatus &= ~lstate.CIST_HOOKED;
}
};
const callhook = function(L, ci) {
let hook = defs.LUA_HOOKCALL;
ci.l_savedpc++; /* hooks assume 'pc' is already incremented */
if ((ci.previous.callstatus & lstate.CIST_LUA) &&
ci.previous.l_code[ci.previous.l_savedpc - 1].opcode == lopcodes.OpCodesI.OP_TAILCALL) {
ci.callstatus |= lstate.CIST_TAIL;
hook = defs.LUA_HOOKTAILCALL;
}
luaD_hook(L, hook, -1);
ci.l_savedpc--; /* correct 'pc' */
};
const adjust_varargs = function(L, p, actual) {
let nfixargs = p.numparams;
/* move fixed parameters to final position */
let fixed = L.top - actual; /* first fixed argument */
let base = L.top; /* final position of first argument */
let i;
for (i = 0; i < nfixargs && i < actual; i++) {
lobject.pushobj2s(L, L.stack[fixed + i]);
L.stack[fixed + i].setnilvalue();
}
for (; i < nfixargs; i++)
L.stack[L.top++] = new lobject.TValue(CT.LUA_TNIL, null);
return base;
};
const tryfuncTM = function(L, off, func) {
let tm = ltm.luaT_gettmbyobj(L, func, ltm.TMS.TM_CALL);
if (!tm.ttisfunction(tm))
ldebug.luaG_typeerror(L, func, defs.to_luastring("call", true));
/* Open a hole inside the stack at 'func' */
lobject.pushobj2s(L, L.stack[L.top-1]); /* push top of stack again */
for (let p = L.top-2; p > off; p--)
lobject.setobjs2s(L, p, p-1); /* move other items up one */
lobject.setobj2s(L, off, tm); /* tag method is the new function to be called */
};
/*
** Check appropriate error for stack overflow ("regular" overflow or
** overflow while handling stack overflow). If 'nCalls' is larger than
** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but
** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to
** allow overflow handling to work)
*/
const stackerror = function(L) {
if (L.nCcalls === llimit.LUAI_MAXCCALLS)
ldebug.luaG_runerror(L, defs.to_luastring("JS stack overflow", true));
else if (L.nCcalls >= llimit.LUAI_MAXCCALLS + (llimit.LUAI_MAXCCALLS >> 3))
luaD_throw(L, TS.LUA_ERRERR); /* error while handing stack error */
};
/*
** Call a function (JS or Lua). The function to be called is at func.
** The arguments are on the stack, right after the function.
** When returns, all the results are on the stack, starting at the original
** function position.
*/
const luaD_call = function(L, off, nResults) {
if (++L.nCcalls >= llimit.LUAI_MAXCCALLS)
stackerror(L);
if (!luaD_precall(L, off, nResults))
lvm.luaV_execute(L);
L.nCcalls--;
};
const luaD_throw = function(L, errcode) {
if (L.errorJmp) { /* thread has an error handler? */
L.errorJmp.status = errcode; /* set status */
throw L.errorJmp;
} else { /* thread has no error handler */
let g = L.l_G;
L.status = errcode; /* mark it as dead */
if (g.mainthread.errorJmp) { /* main thread has a handler? */
g.mainthread.stack[g.mainthread.top++] = L.stack[L.top - 1]; /* copy error obj. */
luaD_throw(g.mainthread, errcode); /* re-throw in main thread */
} else { /* no handler at all; abort */
let panic = g.panic;
if (panic) { /* panic function? */
seterrorobj(L, errcode, L.top); /* assume EXTRA_STACK */
if (L.ci.top < L.top)
L.ci.top = L.top; /* pushing msg. can break this invariant */
panic(L); /* call panic function (last chance to jump out) */
}
throw new Error(`Aborted ${errcode}`);
}
}
};
const luaD_rawrunprotected = function(L, f, ud) {
let oldnCcalls = L.nCcalls;
let lj = { // TODO: necessary when using try/catch ? (ldo.c:47-52)
status: TS.LUA_OK,
previous: L.errorJmp /* chain new error handler */
};
L.errorJmp = lj;
try {
f(L, ud);
} catch (e) {
if (lj.status === TS.LUA_OK) {
/* error was not thrown via luaD_throw, i.e. it is a JS error */
/* run user error handler (if it exists) */
let atnativeerror = L.l_G.atnativeerror;
if (atnativeerror) {
try {
lj.status = TS.LUA_OK;
lapi.lua_pushcfunction(L, atnativeerror);
lapi.lua_pushlightuserdata(L, e);
luaD_callnoyield(L, L.top - 2, 1);
/* Now run the message handler (if it exists) */
/* copy of luaG_errormsg without the throw */
if (L.errfunc !== 0) { /* is there an error handling function? */
let errfunc = L.errfunc;
lobject.pushobj2s(L, L.stack[L.top - 1]); /* move argument */
lobject.setobjs2s(L, L.top - 2, errfunc); /* push function */
luaD_callnoyield(L, L.top - 2, 1);
}
lj.status = TS.LUA_ERRRUN;
} catch(e2) {
if (lj.status === TS.LUA_OK) {
/* also failed */
lj.status = -1;
}
}
} else {
lj.status = -1;
}
}
}
L.errorJmp = lj.previous;
L.nCcalls = oldnCcalls;
return lj.status;
};
/*
** Completes the execution of an interrupted C function, calling its
** continuation function.
*/
const finishCcall = function(L, status) {
let ci = L.ci;
/* must have a continuation and must be able to call it */
assert(ci.c_k !== null && L.nny === 0);
/* error status can only happen in a protected call */
assert(ci.callstatus & lstate.CIST_YPCALL || status === TS.LUA_YIELD);
if (ci.callstatus & TS.CIST_YPCALL) { /* was inside a pcall? */
ci.callstatus &= ~TS.CIST_YPCALL; /* continuation is also inside it */
L.errfunc = ci.c_old_errfunc; /* with the same error function */
}
/* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
handled */
if (ci.nresults === defs.LUA_MULTRET && L.ci.top < L.top) L.ci.top = L.top;
let c_k = ci.c_k; /* don't want to call as method */
let n = c_k(L, status, ci.c_ctx); /* call continuation function */
assert(n < (L.top - L.ci.funcOff), "not enough elements in the stack");
luaD_poscall(L, ci, L.top - n, n); /* finish 'luaD_precall' */
};
/*
** Executes "full continuation" (everything in the stack) of a
** previously interrupted coroutine until the stack is empty (or another
** interruption long-jumps out of the loop). If the coroutine is
** recovering from an error, 'ud' points to the error status, which must
** be passed to the first continuation function (otherwise the default
** status is LUA_YIELD).
*/
const unroll = function(L, ud) {
if (ud !== null) /* error status? */
finishCcall(L, ud); /* finish 'lua_pcallk' callee */
while (L.ci !== L.base_ci) { /* something in the stack */
if (!(L.ci.callstatus & lstate.CIST_LUA)) /* C function? */
finishCcall(L, TS.LUA_YIELD); /* complete its execution */
else { /* Lua function */
lvm.luaV_finishOp(L); /* finish interrupted instruction */
lvm.luaV_execute(L); /* execute down to higher C 'boundary' */
}
}
};
/*
** Try to find a suspended protected call (a "recover point") for the
** given thread.
*/
const findpcall = function(L) {
for (let ci = L.ci; ci !== null; ci = ci.previous) { /* search for a pcall */
if (ci.callstatus & lstate.CIST_YPCALL)
return ci;
}
return null; /* no pending pcall */
};
/*
** Recovers from an error in a coroutine. Finds a recover point (if
** there is one) and completes the execution of the interrupted
** 'luaD_pcall'. If there is no recover point, returns zero.
*/
const recover = function(L, status) {
let ci = findpcall(L);
if (ci === null) return 0; /* no recovery point */
/* "finish" luaD_pcall */
let oldtop = ci.extra;
lfunc.luaF_close(L, oldtop);
seterrorobj(L, status, oldtop);
L.ci = ci;
L.allowhook = ci.callstatus & lstate.CIST_OAH; /* restore original 'allowhook' */
L.nny = 0; /* should be zero to be yieldable */
luaD_shrinkstack(L);
L.errfunc = ci.c_old_errfunc;
return 1; /* continue running the coroutine */
};
/*
** Signal an error in the call to 'lua_resume', not in the execution
** of the coroutine itself. (Such errors should not be handled by any
** coroutine error handler and should not kill the coroutine.)
*/
const resume_error = function(L, msg, narg) {
let ts = lstring.luaS_newliteral(L, msg);
if (narg === 0) {
lobject.pushsvalue2s(L, ts);
assert(L.top <= L.ci.top, "stack overflow");
} else {
/* remove args from the stack */
for (let i=1; i<narg; i++)
delete L.stack[--L.top];
lobject.setsvalue2s(L, L.top-1, ts); /* push error message */
}
return TS.LUA_ERRRUN;
};
/*
** Do the work for 'lua_resume' in protected mode. Most of the work
** depends on the status of the coroutine: initial state, suspended
** inside a hook, or regularly suspended (optionally with a continuation
** function), plus erroneous cases: non-suspended coroutine or dead
** coroutine.
*/
const resume = function(L, n) {
let firstArg = L.top - n; /* first argument */
let ci = L.ci;
if (L.status === TS.LUA_OK) { /* starting a coroutine? */
if (!luaD_precall(L, firstArg - 1, defs.LUA_MULTRET)) /* Lua function? */
lvm.luaV_execute(L); /* call it */
} else { /* resuming from previous yield */
assert(L.status === TS.LUA_YIELD);
L.status = TS.LUA_OK; /* mark that it is running (again) */
ci.funcOff = ci.extra;
ci.func = L.stack[ci.funcOff];
if (ci.callstatus & lstate.CIST_LUA) /* yielded inside a hook? */
lvm.luaV_execute(L); /* just continue running Lua code */
else { /* 'common' yield */
if (ci.c_k !== null) { /* does it have a continuation function? */
n = ci.c_k(L, TS.LUA_YIELD, ci.c_ctx); /* call continuation */
assert(n < (L.top - L.ci.funcOff), "not enough elements in the stack");
firstArg = L.top - n; /* yield results come from continuation */
}
luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */
}
unroll(L, null); /* run continuation */
}
};
const lua_resume = function(L, from, nargs) {
let oldnny = L.nny; /* save "number of non-yieldable" calls */
if (L.status === TS.LUA_OK) { /* may be starting a coroutine */
if (L.ci !== L.base_ci) /* not in base level? */
return resume_error(L, "cannot resume non-suspended coroutine", nargs);
} else if (L.status !== TS.LUA_YIELD)
return resume_error(L, "cannot resume dead coroutine", nargs);
L.nCcalls = from ? from.nCcalls + 1 : 1;
if (L.nCcalls >= llimit.LUAI_MAXCCALLS)
return resume_error(L, "JS stack overflow", nargs);
L.nny = 0; /* allow yields */
assert((L.status === TS.LUA_OK ? nargs + 1: nargs) < (L.top - L.ci.funcOff),
"not enough elements in the stack");
let status = luaD_rawrunprotected(L, resume, nargs);
if (status === -1) /* error calling 'lua_resume'? */
status = TS.LUA_ERRRUN;
else { /* continue running after recoverable errors */
while (status > TS.LUA_YIELD && recover(L, status)) {
/* unroll continuation */
status = luaD_rawrunprotected(L, unroll, status);
}
if (status > TS.LUA_YIELD) { /* unrecoverable error? */
L.status = status; /* mark thread as 'dead' */
seterrorobj(L, status, L.top); /* push error message */
L.ci.top = L.top;
} else
assert(status === L.status); /* normal end or yield */
}
L.nny = oldnny; /* restore 'nny' */
L.nCcalls--;
assert(L.nCcalls === (from ? from.nCcalls : 0));
return status;
};
const lua_isyieldable = function(L) {
return L.nny === 0;
};
const lua_yieldk = function(L, nresults, ctx, k) {
let ci = L.ci;
assert(nresults < (L.top - L.ci.funcOff), "not enough elements in the stack");
if (L.nny > 0) {
if (L !== L.l_G.mainthread)
ldebug.luaG_runerror(L, defs.to_luastring("attempt to yield across a JS-call boundary", true));
else
ldebug.luaG_runerror(L, defs.to_luastring("attempt to yield from outside a coroutine", true));
}
L.status = TS.LUA_YIELD;
ci.extra = ci.funcOff; /* save current 'func' */
if (ci.callstatus & lstate.CIST_LUA) /* inside a hook? */
assert(k === null, "hooks cannot continue after yielding");
else {
ci.c_k = k;
if (k !== null) /* is there a continuation? */
ci.c_ctx = ctx; /* save context */
ci.funcOff = L.top - nresults - 1; /* protect stack below results */
ci.func = L.stack[ci.funcOff];
luaD_throw(L, TS.LUA_YIELD);
}
assert(ci.callstatus & lstate.CIST_HOOKED); /* must be inside a hook */
return 0; /* return to 'luaD_hook' */
};
const lua_yield = function(L, n) {
lua_yieldk(L, n, 0, null);
};
const luaD_pcall = function(L, func, u, old_top, ef) {
let old_ci = L.ci;
let old_allowhooks = L.allowhook;
let old_nny = L.nny;
let old_errfunc = L.errfunc;
L.errfunc = ef;
let status = luaD_rawrunprotected(L, func, u);
if (status !== TS.LUA_OK) {
lfunc.luaF_close(L, old_top);
seterrorobj(L, status, old_top);
L.ci = old_ci;
L.allowhook = old_allowhooks;
L.nny = old_nny;
luaD_shrinkstack(L);
}
L.errfunc = old_errfunc;
return status;
};
/*
** Similar to 'luaD_call', but does not allow yields during the call
*/
const luaD_callnoyield = function(L, off, nResults) {
L.nny++;
luaD_call(L, off, nResults);
L.nny--;
};
/*
** Execute a protected parser.
*/
class SParser {
constructor(z, name, mode) { /* data to 'f_parser' */
this.z = z;
this.buff = new lzio.MBuffer(); /* dynamic structure used by the scanner */
this.dyd = new lparser.Dyndata(); /* dynamic structures used by the parser */
this.mode = mode;
this.name = name;
}
}
const checkmode = function(L, mode, x) {
if (mode && mode.indexOf(x[0]) === -1) {
lapi.lua_pushstring(L, defs.to_luastring(`attempt to load a ${defs.to_jsstring(x)} chunk (mode is '${defs.to_jsstring(mode)}')`));
luaD_throw(L, TS.LUA_ERRSYNTAX);
}
};
const f_parser = function(L, p) {
let cl;
let c = p.z.zgetc(); /* read first character */
if (c === defs.LUA_SIGNATURE.charCodeAt(0)) {
checkmode(L, p.mode, defs.to_luastring("binary", true));
cl = lundump.luaU_undump(L, p.z, p.name);
} else {
checkmode(L, p.mode, defs.to_luastring("text", true));
cl = lparser.luaY_parser(L, p.z, p.buff, p.dyd, p.name, c);
}
assert(cl.nupvalues === cl.p.upvalues.length);
lfunc.luaF_initupvals(L, cl);
};
const luaD_protectedparser = function(L, z, name, mode) {
let p = new SParser(z, name, mode);
L.nny++; /* cannot yield during parsing */
let status = luaD_pcall(L, f_parser, p, L.top, L.errfunc);
L.nny--;
return status;
};
module.exports.adjust_top = adjust_top;
module.exports.luaD_call = luaD_call;
module.exports.luaD_callnoyield = luaD_callnoyield;
module.exports.luaD_checkstack = luaD_checkstack;
module.exports.luaD_growstack = luaD_growstack;
module.exports.luaD_hook = luaD_hook;
module.exports.luaD_inctop = luaD_inctop;
module.exports.luaD_pcall = luaD_pcall;
module.exports.luaD_poscall = luaD_poscall;
module.exports.luaD_precall = luaD_precall;
module.exports.luaD_protectedparser = luaD_protectedparser;
module.exports.luaD_rawrunprotected = luaD_rawrunprotected;
module.exports.luaD_reallocstack = luaD_reallocstack;
module.exports.luaD_throw = luaD_throw;
module.exports.lua_isyieldable = lua_isyieldable;
module.exports.lua_resume = lua_resume;
module.exports.lua_yield = lua_yield;
module.exports.lua_yieldk = lua_yieldk;
/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const ldebug = __webpack_require__(19);
const lobject = __webpack_require__(5);
const lstring = __webpack_require__(15);
const lstate = __webpack_require__(21);
const CT = defs.constant_types;
/* used to prevent conflicts with lightuserdata keys */
let lightuserdata_hashes = new WeakMap();
const get_lightuserdata_hash = function(v) {
let hash = lightuserdata_hashes.get(v);
if (!hash) {
/* Hash should be something unique that is a valid WeakMap key
so that it ends up in dead_weak when removed from a table */
hash = {};
lightuserdata_hashes.set(v, hash);
}
return hash;
};
const table_hash = function(L, key) {
switch(key.type) {
case CT.LUA_TNIL:
return ldebug.luaG_runerror(L, defs.to_luastring("table index is nil", true));
case CT.LUA_TNUMFLT:
if (isNaN(key.value))
return ldebug.luaG_runerror(L, defs.to_luastring("table index is NaN", true));
/* fall through */
case CT.LUA_TNUMINT: /* takes advantage of floats and integers being same in JS */
case CT.LUA_TBOOLEAN:
case CT.LUA_TTABLE:
case CT.LUA_TLCL:
case CT.LUA_TLCF:
case CT.LUA_TCCL:
case CT.LUA_TUSERDATA:
case CT.LUA_TTHREAD:
return key.value;
case CT.LUA_TSHRSTR:
case CT.LUA_TLNGSTR:
return lstring.luaS_hashlongstr(key.tsvalue());
case CT.LUA_TLIGHTUSERDATA:
let v = key.value;
switch(typeof v) {
case "string":
/* possible conflict with LUA_TSTRING.
prefix this string with "*" so they don't clash */
return "*" + v;
case "number":
/* possible conflict with LUA_TNUMBER.
turn into string and prefix with "#" to avoid clash with other strings */
return "#" + v;
case "boolean":
/* possible conflict with LUA_TBOOLEAN. use strings ?true and ?false instead */
return v?"?true":"?false";
case "function":
/* possible conflict with LUA_TLCF.
indirect via a weakmap */
return get_lightuserdata_hash(v);
case "object":
/* v could be a lua_State, CClosure, LClosure, Table or Userdata from this state as returned by lua_topointer */
if ((v instanceof lstate.lua_State && v.l_G === L.l_G) ||
v instanceof Table ||
v instanceof lobject.Udata ||
v instanceof lobject.LClosure ||
v instanceof lobject.CClosure) {
/* indirect via a weakmap */
return get_lightuserdata_hash(v);
}
/* fall through */
default:
return v;
}
default:
throw new Error("unknown key type: " + key.type);
}
};
class Table {
constructor(L) {
this.id = L.l_G.id_counter++;
this.strong = new Map();
this.dead_strong = new Map();
this.dead_weak = void 0; /* initialised when needed */
this.f = void 0; /* first entry */
this.l = void 0; /* last entry */
this.metatable = null;
this.flags = ~0;
}
}
const invalidateTMcache = function(t) {
t.flags = 0;
};
const add = function(t, hash, key, value) {
t.dead_strong.clear();
t.dead_weak = void 0;
let prev = null;
let entry = {
key: key,
value: value,
p: prev = t.l,
n: void 0
};
if (!t.f) t.f = entry;
if (prev) prev.n = entry;
t.strong.set(hash, entry);
t.l = entry;
};
const is_valid_weakmap_key = function(k) {
return typeof k === 'object' ? k !== null : typeof k === 'function';
};
/* Move out of 'strong' part and into 'dead' part. */
const mark_dead = function(t, hash) {
let e = t.strong.get(hash);
if (e) {
e.key.setdeadvalue();
e.value = void 0;
let next = e.n;
let prev = e.p;
e.p = void 0; /* no need to know previous item any more */
if(prev) prev.n = next;
if(next) next.p = prev;
if(t.f === e) t.f = next;
if(t.l === e) t.l = prev;
t.strong.delete(hash);
if (is_valid_weakmap_key(hash)) {
if (!t.dead_weak) t.dead_weak = new WeakMap();
t.dead_weak.set(hash, e);
} else {
/* can't be used as key in weakmap */
t.dead_strong.set(hash, e);
}
}
};
const luaH_new = function(L) {
return new Table(L);
};
const getgeneric = function(t, hash) {
let v = t.strong.get(hash);
return v ? v.value : lobject.luaO_nilobject;
};
const luaH_getint = function(t, key) {
assert(typeof key == "number" && (key|0) === key);
return getgeneric(t, key);
};
const luaH_getstr = function(t, key) {
assert(key instanceof lstring.TString);
return getgeneric(t, lstring.luaS_hashlongstr(key));
};
const luaH_get = function(L, t, key) {
assert(key instanceof lobject.TValue);
if (key.ttisnil() || (key.ttisfloat() && isNaN(key.value)))
return lobject.luaO_nilobject;
return getgeneric(t, table_hash(L, key));
};
const setgeneric = function(t, hash, key) {
let v = t.strong.get(hash);
if (v)
return v.value;
let kv = key.value;
if ((key.ttisfloat() && (kv|0) === kv)) { /* does index fit in an integer? */
/* insert it as an integer */
key = new lobject.TValue(CT.LUA_TNUMINT, kv);
} else {
key = new lobject.TValue(key.type, kv);
}
let tv = new lobject.TValue(CT.LUA_TNIL, null);
add(t, hash, key, tv);
return tv;
};
const luaH_setint = function(t, key, value) {
assert(typeof key == "number" && (key|0) === key && value instanceof lobject.TValue);
let hash = key; /* table_hash known result */
if (value.ttisnil()) {
mark_dead(t, hash);
return;
}
let v = t.strong.get(hash);
if (v) {
let tv = v.value;
tv.setfrom(value);
} else {
let k = new lobject.TValue(CT.LUA_TNUMINT, key);
let v = new lobject.TValue(value.type, value.value);
add(t, hash, k, v);
}
};
const luaH_set = function(L, t, key) {
assert(key instanceof lobject.TValue);
let hash = table_hash(L, key);
return setgeneric(t, hash, key);
};
const luaH_delete = function(L, t, key) {
assert(key instanceof lobject.TValue);
let hash = table_hash(L, key);
return mark_dead(t, hash);
};
/*
** Try to find a boundary in table 't'. A 'boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
const luaH_getn = function(t) {
let i = 0;
let j = t.strong.size + 1; /* use known size of Map to bound search */
/* now do a binary search between them */
while (j - i > 1) {
let m = Math.floor((i+j)/2);
if (luaH_getint(t, m).ttisnil()) j = m;
else i = m;
}
return i;
};
const luaH_next = function(L, table, keyI) {
let keyO = L.stack[keyI];
let entry;
if (keyO.type === CT.LUA_TNIL) {
entry = table.f;
if (!entry)
return false;
} else {
/* First find current key */
let hash = table_hash(L, keyO);
/* Look in main part of table */
entry = table.strong.get(hash);
if (entry) {
entry = entry.n;
if (!entry)
return false;
} else {
/* Try dead keys */
entry = (table.dead_weak && table.dead_weak.get(hash)) || table.dead_strong.get(hash);
if (!entry)
/* item not in table */
return ldebug.luaG_runerror(L, defs.to_luastring("invalid key to 'next'"));
/* Iterate until either out of keys, or until finding a non-dead key */
do {
entry = entry.n;
if (!entry)
return false;
} while (entry.key.ttisdeadkey());
}
}
lobject.setobj2s(L, keyI, entry.key);
lobject.setobj2s(L, keyI+1, entry.value);
return true;
};
module.exports.invalidateTMcache = invalidateTMcache;
module.exports.luaH_delete = luaH_delete;
module.exports.luaH_get = luaH_get;
module.exports.luaH_getint = luaH_getint;
module.exports.luaH_getn = luaH_getn;
module.exports.luaH_getstr = luaH_getstr;
module.exports.luaH_set = luaH_set;
module.exports.luaH_setint = luaH_setint;
module.exports.luaH_new = luaH_new;
module.exports.luaH_next = luaH_next;
module.exports.Table = Table;
/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
class TString {
constructor(L, str) {
this.hash = null;
this.realstring = str;
}
getstr() {
return this.realstring;
}
tsslen() {
return this.realstring.length;
}
}
const luaS_eqlngstr = function(a, b) {
assert(a instanceof TString);
assert(b instanceof TString);
return a == b || (a.realstring.length == b.realstring.length && a.realstring.join() == b.realstring.join());
};
/* converts strings (arrays) to a consistent map key
make sure this doesn't conflict with any of the anti-collision strategies in ltable */
const luaS_hash = function(str) {
assert(defs.is_luastring(str));
return str.map(e => `${e}|`).join('');
};
const luaS_hashlongstr = function(ts) {
assert(ts instanceof TString);
if(ts.hash === null) {
ts.hash = luaS_hash(ts.getstr());
}
return ts.hash;
};
/* variant that takes ownership of array */
const luaS_bless = function(L, str) {
return new TString(L, str);
};
/* makes a copy */
const luaS_new = function(L, str) {
return luaS_bless(L, str.slice(0));
};
/* takes a js string */
const luaS_newliteral = function(L, str) {
return luaS_bless(L, defs.to_luastring(str));
};
module.exports.luaS_eqlngstr = luaS_eqlngstr;
module.exports.luaS_hash = luaS_hash;
module.exports.luaS_hashlongstr = luaS_hashlongstr;
module.exports.luaS_bless = luaS_bless;
module.exports.luaS_new = luaS_new;
module.exports.luaS_newliteral = luaS_newliteral;
module.exports.TString = TString;
/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const ldebug = __webpack_require__(23);
const lobject = __webpack_require__(7);
const lstring = __webpack_require__(17);
const lstate = __webpack_require__(25);
const CT = defs.constant_types;
/* used to prevent conflicts with lightuserdata keys */
let lightuserdata_hashes = new WeakMap();
const get_lightuserdata_hash = function(v) {
let hash = lightuserdata_hashes.get(v);
if (!hash) {
/* Hash should be something unique that is a valid WeakMap key
so that it ends up in dead_weak when removed from a table */
hash = {};
lightuserdata_hashes.set(v, hash);
}
return hash;
};
const table_hash = function(L, key) {
switch(key.type) {
case CT.LUA_TNIL:
return ldebug.luaG_runerror(L, defs.to_luastring("table index is nil", true));
case CT.LUA_TNUMFLT:
if (isNaN(key.value))
return ldebug.luaG_runerror(L, defs.to_luastring("table index is NaN", true));
/* fall through */
case CT.LUA_TNUMINT: /* takes advantage of floats and integers being same in JS */
case CT.LUA_TBOOLEAN:
case CT.LUA_TTABLE:
case CT.LUA_TLCL:
case CT.LUA_TLCF:
case CT.LUA_TCCL:
case CT.LUA_TUSERDATA:
case CT.LUA_TTHREAD:
return key.value;
case CT.LUA_TSHRSTR:
case CT.LUA_TLNGSTR:
return lstring.luaS_hashlongstr(key.tsvalue());
case CT.LUA_TLIGHTUSERDATA:
let v = key.value;
switch(typeof v) {
case "string":
/* possible conflict with LUA_TSTRING.
prefix this string with "*" so they don't clash */
return "*" + v;
case "number":
/* possible conflict with LUA_TNUMBER.
turn into string and prefix with "#" to avoid clash with other strings */
return "#" + v;
case "boolean":
/* possible conflict with LUA_TBOOLEAN. use strings ?true and ?false instead */
return v?"?true":"?false";
case "function":
/* possible conflict with LUA_TLCF.
indirect via a weakmap */
return get_lightuserdata_hash(v);
case "object":
/* v could be a lua_State, CClosure, LClosure, Table or Userdata from this state as returned by lua_topointer */
if ((v instanceof lstate.lua_State && v.l_G === L.l_G) ||
v instanceof Table ||
v instanceof lobject.Udata ||
v instanceof lobject.LClosure ||
v instanceof lobject.CClosure) {
/* indirect via a weakmap */
return get_lightuserdata_hash(v);
}
/* fall through */
default:
return v;
}
default:
throw new Error("unknown key type: " + key.type);
}
};
class Table {
constructor(L) {
this.id = L.l_G.id_counter++;
this.strong = new Map();
this.dead_strong = new Map();
this.dead_weak = void 0; /* initialised when needed */
this.f = void 0; /* first entry */
this.l = void 0; /* last entry */
this.metatable = null;
this.flags = ~0;
}
}
const invalidateTMcache = function(t) {
t.flags = 0;
};
const add = function(t, hash, key, value) {
t.dead_strong.clear();
t.dead_weak = void 0;
let prev = null;
let entry = {
key: key,
value: value,
p: prev = t.l,
n: void 0
};
if (!t.f) t.f = entry;
if (prev) prev.n = entry;
t.strong.set(hash, entry);
t.l = entry;
};
const is_valid_weakmap_key = function(k) {
return typeof k === 'object' ? k !== null : typeof k === 'function';
};
/* Move out of 'strong' part and into 'dead' part. */
const mark_dead = function(t, hash) {
let e = t.strong.get(hash);
if (e) {
e.key.setdeadvalue();
e.value = void 0;
let next = e.n;
let prev = e.p;
e.p = void 0; /* no need to know previous item any more */
if(prev) prev.n = next;
if(next) next.p = prev;
if(t.f === e) t.f = next;
if(t.l === e) t.l = prev;
t.strong.delete(hash);
if (is_valid_weakmap_key(hash)) {
if (!t.dead_weak) t.dead_weak = new WeakMap();
t.dead_weak.set(hash, e);
} else {
/* can't be used as key in weakmap */
t.dead_strong.set(hash, e);
}
}
};
const luaH_new = function(L) {
return new Table(L);
};
const getgeneric = function(t, hash) {
let v = t.strong.get(hash);
return v ? v.value : lobject.luaO_nilobject;
};
const luaH_getint = function(t, key) {
assert(typeof key == "number" && (key|0) === key);
return getgeneric(t, key);
};
const luaH_getstr = function(t, key) {
assert(key instanceof lstring.TString);
return getgeneric(t, lstring.luaS_hashlongstr(key));
};
const luaH_get = function(L, t, key) {
assert(key instanceof lobject.TValue);
if (key.ttisnil() || (key.ttisfloat() && isNaN(key.value)))
return lobject.luaO_nilobject;
return getgeneric(t, table_hash(L, key));
};
const setgeneric = function(t, hash, key) {
let v = t.strong.get(hash);
if (v)
return v.value;
let kv = key.value;
if ((key.ttisfloat() && (kv|0) === kv)) { /* does index fit in an integer? */
/* insert it as an integer */
key = new lobject.TValue(CT.LUA_TNUMINT, kv);
} else {
key = new lobject.TValue(key.type, kv);
}
let tv = new lobject.TValue(CT.LUA_TNIL, null);
add(t, hash, key, tv);
return tv;
};
const luaH_setint = function(t, key, value) {
assert(typeof key == "number" && (key|0) === key && value instanceof lobject.TValue);
let hash = key; /* table_hash known result */
if (value.ttisnil()) {
mark_dead(t, hash);
return;
}
let v = t.strong.get(hash);
if (v) {
let tv = v.value;
tv.setfrom(value);
} else {
let k = new lobject.TValue(CT.LUA_TNUMINT, key);
let v = new lobject.TValue(value.type, value.value);
add(t, hash, k, v);
}
};
const luaH_set = function(L, t, key) {
assert(key instanceof lobject.TValue);
let hash = table_hash(L, key);
return setgeneric(t, hash, key);
};
const luaH_delete = function(L, t, key) {
assert(key instanceof lobject.TValue);
let hash = table_hash(L, key);
return mark_dead(t, hash);
};
/*
** Try to find a boundary in table 't'. A 'boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
const luaH_getn = function(t) {
let i = 0;
let j = t.strong.size + 1; /* use known size of Map to bound search */
/* now do a binary search between them */
while (j - i > 1) {
let m = Math.floor((i+j)/2);
if (luaH_getint(t, m).ttisnil()) j = m;
else i = m;
}
return i;
};
const luaH_next = function(L, table, keyI) {
let keyO = L.stack[keyI];
let entry;
if (keyO.type === CT.LUA_TNIL) {
entry = table.f;
if (!entry)
return false;
} else {
/* First find current key */
let hash = table_hash(L, keyO);
/* Look in main part of table */
entry = table.strong.get(hash);
if (entry) {
entry = entry.n;
if (!entry)
return false;
} else {
/* Try dead keys */
entry = (table.dead_weak && table.dead_weak.get(hash)) || table.dead_strong.get(hash);
if (!entry)
/* item not in table */
return ldebug.luaG_runerror(L, defs.to_luastring("invalid key to 'next'"));
/* Iterate until either out of keys, or until finding a non-dead key */
do {
entry = entry.n;
if (!entry)
return false;
} while (entry.key.ttisdeadkey());
}
}
lobject.setobj2s(L, keyI, entry.key);
lobject.setobj2s(L, keyI+1, entry.value);
return true;
};
module.exports.invalidateTMcache = invalidateTMcache;
module.exports.luaH_delete = luaH_delete;
module.exports.luaH_get = luaH_get;
module.exports.luaH_getint = luaH_getint;
module.exports.luaH_getn = luaH_getn;
module.exports.luaH_getstr = luaH_getstr;
module.exports.luaH_set = luaH_set;
module.exports.luaH_setint = luaH_setint;
module.exports.luaH_new = luaH_new;
module.exports.luaH_next = luaH_next;
module.exports.Table = Table;
/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
class TString {
constructor(L, str) {
this.hash = null;
this.realstring = str;
}
getstr() {
return this.realstring;
}
tsslen() {
return this.realstring.length;
}
}
const luaS_eqlngstr = function(a, b) {
assert(a instanceof TString);
assert(b instanceof TString);
return a == b || (a.realstring.length == b.realstring.length && a.realstring.join() == b.realstring.join());
};
/* converts strings (arrays) to a consistent map key
make sure this doesn't conflict with any of the anti-collision strategies in ltable */
const luaS_hash = function(str) {
assert(defs.is_luastring(str));
return str.map(e => `${e}|`).join('');
};
const luaS_hashlongstr = function(ts) {
assert(ts instanceof TString);
if(ts.hash === null) {
ts.hash = luaS_hash(ts.getstr());
}
return ts.hash;
};
/* variant that takes ownership of array */
const luaS_bless = function(L, str) {
return new TString(L, str);
};
/* makes a copy */
const luaS_new = function(L, str) {
return luaS_bless(L, str.slice(0));
};
/* takes a js string */
const luaS_newliteral = function(L, str) {
return luaS_bless(L, defs.to_luastring(str));
};
module.exports.luaS_eqlngstr = luaS_eqlngstr;
module.exports.luaS_hash = luaS_hash;
module.exports.luaS_hashlongstr = luaS_hashlongstr;
module.exports.luaS_bless = luaS_bless;
module.exports.luaS_new = luaS_new;
module.exports.luaS_newliteral = luaS_newliteral;
module.exports.TString = TString;
/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const llimit = __webpack_require__(8);
const sprintf = __webpack_require__(34).sprintf;
/*
@@ LUAI_MAXSTACK limits the size of the Lua stack.
** CHANGE it if you need a different limit. This limit is arbitrary;
** its only purpose is to stop Lua from consuming unlimited stack
** space (and to reserve some numbers for pseudo-indices).
*/
/* TODO: put back to 1000000. Node would go out of memory in some cases (e.g. travis) */
const LUAI_MAXSTACK = 100000;
/*
@@ LUA_IDSIZE gives the maximum size for the description of the source
@@ of a function in debug information.
** CHANGE it if you want a different size.
*/
const LUA_IDSIZE = 60;
const lua_integer2str = function(n) {
return sprintf(LUA_INTEGER_FMT, n);
};
const lua_number2str = function(n) {
return sprintf(LUA_NUMBER_FMT, n);
};
const lua_numbertointeger = function(n) {
return n >= llimit.MIN_INT && n < -llimit.MIN_INT ? n : false;
};
const LUA_INTEGER_FRMLEN = "";
const LUA_NUMBER_FRMLEN = "";
const LUA_INTEGER_FMT = `%${LUA_INTEGER_FRMLEN}d`;
const LUA_NUMBER_FMT = "%.14g";
const lua_getlocaledecpoint = function() {
return (1.1).toLocaleString().substring(1, 2);
};
// See: http://croquetweak.blogspot.fr/2014/08/deconstructing-floats-frexp-and-ldexp.html
const frexp = function(value) {
if (value === 0) return [value, 0];
var data = new DataView(new ArrayBuffer(8));
data.setFloat64(0, value);
var bits = (data.getUint32(0) >>> 20) & 0x7FF;
if (bits === 0) { // denormal
data.setFloat64(0, value * Math.pow(2, 64)); // exp + 64
bits = ((data.getUint32(0) >>> 20) & 0x7FF) - 64;
}
var exponent = bits - 1022;
var mantissa = ldexp(value, -exponent);
return [mantissa, exponent];
};
const ldexp = function(mantissa, exponent) {
var steps = Math.min(3, Math.ceil(Math.abs(exponent) / 1023));
var result = mantissa;
for (var i = 0; i < steps; i++)
result *= Math.pow(2, Math.floor((exponent + i) / steps));
return result;
};
module.exports.frexp = frexp;
module.exports.ldexp = ldexp;
module.exports.LUAI_MAXSTACK = LUAI_MAXSTACK;
module.exports.LUA_IDSIZE = LUA_IDSIZE;
module.exports.LUA_INTEGER_FMT = LUA_INTEGER_FMT;
module.exports.LUA_INTEGER_FRMLEN = LUA_INTEGER_FRMLEN;
module.exports.LUA_NUMBER_FMT = LUA_NUMBER_FMT;
module.exports.LUA_NUMBER_FRMLEN = LUA_NUMBER_FRMLEN;
module.exports.lua_getlocaledecpoint = lua_getlocaledecpoint;
module.exports.lua_integer2str = lua_integer2str;
module.exports.lua_number2str = lua_number2str;
module.exports.lua_numbertointeger = lua_numbertointeger;
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const ldo = __webpack_require__(12);
const lfunc = __webpack_require__(20);
const lobject = __webpack_require__(5);
const lopcodes = __webpack_require__(28);
const lstate = __webpack_require__(21);
const ltable = __webpack_require__(14);
const ltm = __webpack_require__(26);
const luaconf = __webpack_require__(18);
const lvm = __webpack_require__(27);
const CT = defs.constant_types;
const TS = defs.thread_status;
const currentpc = function(ci) {
assert(ci.callstatus & lstate.CIST_LUA);
return ci.l_savedpc - 1;
};
const currentline = function(ci) {
return ci.func.value.p.lineinfo.length !== 0 ? ci.func.value.p.lineinfo[currentpc(ci)] : -1;
};
/*
** If function yielded, its 'func' can be in the 'extra' field. The
** next function restores 'func' to its correct value for debugging
** purposes. (It exchanges 'func' and 'extra'; so, when called again,
** after debugging, it also "re-restores" ** 'func' to its altered value.
*/
const swapextra = function(L) {
if (L.status === TS.LUA_YIELD) {
let ci = L.ci; /* get function that yielded */
let temp = ci.funcOff; /* exchange its 'func' and 'extra' values */
ci.func = L.stack[ci.extra];
ci.funcOff = ci.extra;
ci.extra = temp;
}
};
const lua_sethook = function(L, func, mask, count) {
if (func === null || mask === 0) { /* turn off hooks? */
mask = 0;
func = null;
}
if (L.ci.callstatus & lstate.CIST_LUA)
L.oldpc = L.ci.l_savedpc;
L.hook = func;
L.basehookcount = count;
L.hookcount = L.basehookcount;
L.hookmask = mask;
};
const lua_gethook = function(L) {
return L.hook;
};
const lua_gethookmask = function(L) {
return L.hookmask;
};
const lua_gethookcount = function(L) {
return L.basehookcount;
};
const lua_getstack = function(L, level, ar) {
let ci;
let status;
if (level < 0) return 0; /* invalid (negative) level */
for (ci = L.ci; level > 0 && ci !== L.base_ci; ci = ci.previous)
level--;
if (level === 0 && ci !== L.base_ci) { /* level found? */
status = 1;
ar.i_ci = ci;
} else
status = 0; /* no such level */
return status;
};
const upvalname = function(p, uv) {
assert(uv < p.upvalues.length);
let s = p.upvalues[uv].name;
if (s === null) return ["?".charCodeAt(0)];
return s.getstr();
};
const findvararg = function(ci, n) {
let nparams = ci.func.value.p.numparams;
if (n >= ci.l_base - ci.funcOff - nparams)
return null; /* no such vararg */
else {
return {
pos: ci.funcOff + nparams + n,
name: defs.to_luastring("(*vararg)", true) /* generic name for any vararg */
};
}
};
const findlocal = function(L, ci, n) {
let base, name = null;
if (ci.callstatus & lstate.CIST_LUA) {
if (n < 0) /* access to vararg values? */
return findvararg(ci, -n);
else {
base = ci.l_base;
name = lfunc.luaF_getlocalname(ci.func.value.p, n, currentpc(ci));
}
} else
base = ci.funcOff + 1;
if (name === null) { /* no 'standard' name? */
let limit = ci === L.ci ? L.top : ci.next.funcOff;
if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
name = defs.to_luastring("(*temporary)", true); /* generic name for any valid slot */
else
return null; /* no name */
}
return {
pos: base + (n - 1),
name: name
};
};
const lua_getlocal = function(L, ar, n) {
let name;
swapextra(L);
if (ar === null) { /* information about non-active function? */
if (!L.stack[L.top - 1].ttisLclosure()) /* not a Lua function? */
name = null;
else /* consider live variables at function start (parameters) */
name = lfunc.luaF_getlocalname(L.stack[L.top - 1].value.p, n, 0);
} else { /* active function; get information through 'ar' */
let local = findlocal(L, ar.i_ci, n);
if (local) {
name = local.name;
lobject.pushobj2s(L, L.stack[local.pos]);
assert(L.top <= L.ci.top, "stack overflow");
} else {
name = null;
}
}
swapextra(L);
return name;
};
const lua_setlocal = function(L, ar, n) {
let name;
swapextra(L);
let local = findlocal(L, ar.i_ci, n);
if (local) {
name = local.name;
lobject.setobjs2s(L, local.pos, L.top - 1);
delete L.stack[--L.top]; /* pop value */
} else {
name = null;
}
swapextra(L);
return name;
};
const funcinfo = function(ar, cl) {
if (cl === null || cl instanceof lobject.CClosure) {
ar.source = defs.to_luastring("=[JS]", true);
ar.linedefined = -1;
ar.lastlinedefined = -1;
ar.what = ["J".charCodeAt(0)];
} else {
let p = cl.p;
ar.source = p.source ? p.source.getstr() : defs.to_luastring("=?", true);
ar.linedefined = p.linedefined;
ar.lastlinedefined = p.lastlinedefined;
ar.what = ar.linedefined === 0 ? defs.to_luastring("main", true) : defs.to_luastring("Lua", true);
}
ar.short_src = lobject.luaO_chunkid(ar.source, luaconf.LUA_IDSIZE);
};
const collectvalidlines = function(L, f) {
if (f === null || f instanceof lobject.CClosure) {
L.stack[L.top] = new lobject.TValue(CT.LUA_TNIL, null);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
} else {
let lineinfo = f.p.lineinfo;
let t = ltable.luaH_new(L);
L.stack[L.top] = new lobject.TValue(CT.LUA_TTABLE, t);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
let v = new lobject.TValue(CT.LUA_TBOOLEAN, true);
for (let i = 0; i < lineinfo.length; i++)
ltable.luaH_setint(t, lineinfo[i], v);
}
};
const getfuncname = function(L, ci) {
let r = {
name: null,
funcname: null
};
if (ci === null)
return null;
else if (ci.callstatus & lstate.CIST_FIN) { /* is this a finalizer? */
r.name = defs.to_luastring("__gc", true);
r.funcname = defs.to_luastring("metamethod", true); /* report it as such */
return r;
}
/* calling function is a known Lua function? */
else if (!(ci.callstatus & lstate.CIST_TAIL) && ci.previous.callstatus & lstate.CIST_LUA)
return funcnamefromcode(L, ci.previous);
else return null; /* no way to find a name */
};
const auxgetinfo = function(L, what, ar, f, ci) {
let status = 1;
for (; what.length > 0; what = what.slice(1)) {
switch (String.fromCharCode(what[0])) {
case 'S': {
funcinfo(ar, f);
break;
}
case 'l': {
ar.currentline = ci && ci.callstatus & lstate.CIST_LUA ? currentline(ci) : -1;
break;
}
case 'u': {
ar.nups = f === null ? 0 : f.nupvalues;
if (f === null || f instanceof lobject.CClosure) {
ar.isvararg = true;
ar.nparams = 0;
} else {
ar.isvararg = f.p.is_vararg;
ar.nparams = f.p.numparams;
}
break;
}
case 't': {
ar.istailcall = ci ? ci.callstatus & lstate.CIST_TAIL : 0;
break;
}
case 'n': {
let r = getfuncname(L, ci);
if (r === null) {
ar.namewhat = [];
ar.name = null;
} else {
ar.namewhat = r.funcname;
ar.name = r.name;
}
break;
}
case 'L':
case 'f': /* handled by lua_getinfo */
break;
default: status = 0; /* invalid option */
}
}
return status;
};
const lua_getinfo = function(L, what, ar) {
let status, cl, ci, func;
swapextra(L);
if (what[0] === '>'.charCodeAt(0)) {
ci = null;
func = L.stack[L.top - 1];
assert(L, func.ttisfunction(), "function expected");
what = what.slice(1); /* skip the '>' */
L.top--; /* pop function */
} else {
ci = ar.i_ci;
func = ci.func;
assert(ci.func.ttisfunction());
}
cl = func.ttisclosure() ? func.value : null;
status = auxgetinfo(L, what, ar, cl, ci);
if (what.indexOf('f'.charCodeAt(0)) >= 0) {
lobject.pushobj2s(L, func);
assert(L.top <= L.ci.top, "stack overflow");
}
swapextra(L);
if (what.indexOf('L'.charCodeAt(0)) >= 0)
collectvalidlines(L, cl);
return status;
};
const kname = function(p, pc, c) {
let r = {
name: null,
funcname: null
};
if (lopcodes.ISK(c)) { /* is 'c' a constant? */
let kvalue = p.k[lopcodes.INDEXK(c)];
if (kvalue.ttisstring()) { /* literal constant? */
r.name = kvalue.svalue(); /* it is its own name */
return r;
}
/* else no reasonable name found */
} else { /* 'c' is a register */
let what = getobjname(p, pc, c); /* search for 'c' */
if (what && what.funcname[0] === 'c'.charCodeAt(0)) { /* found a constant name? */
return what; /* 'name' already filled */
}
/* else no reasonable name found */
}
r.name = [defs.char["?"]];
return r; /* no reasonable name found */
};
const filterpc = function(pc, jmptarget) {
if (pc < jmptarget) /* is code conditional (inside a jump)? */
return -1; /* cannot know who sets that register */
else return pc; /* current position sets that register */
};
/*
** try to find last instruction before 'lastpc' that modified register 'reg'
*/
const findsetreg = function(p, lastpc, reg) {
let setreg = -1; /* keep last instruction that changed 'reg' */
let jmptarget = 0; /* any code before this address is conditional */
let OCi = lopcodes.OpCodesI;
for (let pc = 0; pc < lastpc; pc++) {
let i = p.code[pc];
let a = i.A;
switch (i.opcode) {
case OCi.OP_LOADNIL: {
let b = i.B;
if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
setreg = filterpc(pc, jmptarget);
break;
}
case OCi.OP_TFORCALL: {
if (reg >= a + 2) /* affect all regs above its base */
setreg = filterpc(pc, jmptarget);
break;
}
case OCi.OP_CALL:
case OCi.OP_TAILCALL: {
if (reg >= a) /* affect all registers above base */
setreg = filterpc(pc, jmptarget);
break;
}
case OCi.OP_JMP: {
let b = i.sBx;
let dest = pc + 1 + b;
/* jump is forward and do not skip 'lastpc'? */
if (pc < dest && dest <= lastpc) {
if (dest > jmptarget)
jmptarget = dest; /* update 'jmptarget' */
}
break;
}
default:
if (lopcodes.testAMode(i.opcode) && reg === a)
setreg = filterpc(pc, jmptarget);
break;
}
}
return setreg;
};
const getobjname = function(p, lastpc, reg) {
let r = {
name: lfunc.luaF_getlocalname(p, reg + 1, lastpc),
funcname: null
};
if (r.name) { /* is a local? */
r.funcname = defs.to_luastring("local", true);
return r;
}
/* else try symbolic execution */
let pc = findsetreg(p, lastpc, reg);
let OCi = lopcodes.OpCodesI;
if (pc !== -1) { /* could find instruction? */
let i = p.code[pc];
switch (i.opcode) {
case OCi.OP_MOVE: {
let b = i.B; /* move from 'b' to 'a' */
if (b < i.A)
return getobjname(p, pc, b); /* get name for 'b' */
break;
}
case OCi.OP_GETTABUP:
case OCi.OP_GETTABLE: {
let k = i.C; /* key index */
let t = i.B; /* table index */
let vn = i.opcode === OCi.OP_GETTABLE ? lfunc.luaF_getlocalname(p, t + 1, pc) : upvalname(p, t);
r.name = kname(p, pc, k).name;
r.funcname = vn && defs.to_jsstring(vn) === "_ENV" ? defs.to_luastring("global", true) : defs.to_luastring("field", true);
return r;
}
case OCi.OP_GETUPVAL: {
r.name = upvalname(p, i.B);
r.funcname = defs.to_luastring("upvalue", true);
return r;
}
case OCi.OP_LOADK:
case OCi.OP_LOADKX: {
let b = i.opcode === OCi.OP_LOADK ? i.Bx : p.code[pc + 1].Ax;
if (p.k[b].ttisstring()) {
r.name = p.k[b].svalue();
r.funcname = defs.to_luastring("constant", true);
return r;
}
break;
}
case OCi.OP_SELF: {
let k = i.C;
r.name = kname(p, pc, k).name;
r.funcname = defs.to_luastring("method", true);
return r;
}
default: break;
}
}
return null;
};
/*
** Try to find a name for a function based on the code that called it.
** (Only works when function was called by a Lua function.)
** Returns what the name is (e.g., "for iterator", "method",
** "metamethod") and sets '*name' to point to the name.
*/
const funcnamefromcode = function(L, ci) {
let r = {
name: null,
funcname: null
};
let tm = 0; /* (initial value avoids warnings) */
let p = ci.func.value.p; /* calling function */
let pc = currentpc(ci); /* calling instruction index */
let i = p.code[pc]; /* calling instruction */
let OCi = lopcodes.OpCodesI;
if (ci.callstatus & lstate.CIST_HOOKED) {
r.name = [defs.char["?"]];
r.funcname = defs.to_luastring("hook", true);
return r;
}
switch (i.opcode) {
case OCi.OP_CALL:
case OCi.OP_TAILCALL:
return getobjname(p, pc, i.A); /* get function name */
case OCi.OP_TFORCALL:
r.name = defs.to_luastring("for iterator", true);
r.funcname = defs.to_luastring("for iterator", true);
return r;
/* other instructions can do calls through metamethods */
case OCi.OP_SELF:
case OCi.OP_GETTABUP:
case OCi.OP_GETTABLE:
tm = ltm.TMS.TM_INDEX;
break;
case OCi.OP_SETTABUP:
case OCi.OP_SETTABLE:
tm = ltm.TMS.TM_NEWINDEX;
break;
case OCi.OP_ADD: tm = ltm.TMS.TM_ADD; break;
case OCi.OP_SUB: tm = ltm.TMS.TM_SUB; break;
case OCi.OP_MUL: tm = ltm.TMS.TM_MUL; break;
case OCi.OP_MOD: tm = ltm.TMS.TM_MOD; break;
case OCi.OP_POW: tm = ltm.TMS.TM_POW; break;
case OCi.OP_DIV: tm = ltm.TMS.TM_DIV; break;
case OCi.OP_IDIV: tm = ltm.TMS.TM_IDIV; break;
case OCi.OP_BAND: tm = ltm.TMS.TM_BAND; break;
case OCi.OP_BOR: tm = ltm.TMS.TM_BOR; break;
case OCi.OP_BXOR: tm = ltm.TMS.TM_BXOR; break;
case OCi.OP_SHL: tm = ltm.TMS.TM_SHL; break;
case OCi.OP_SHR: tm = ltm.TMS.TM_SHR; break;
case OCi.OP_UNM: tm = ltm.TMS.TM_UNM; break;
case OCi.OP_BNOT: tm = ltm.TMS.TM_BNOT; break;
case OCi.OP_LEN: tm = ltm.TMS.TM_LEN; break;
case OCi.OP_CONCAT: tm = ltm.TMS.TM_CONCAT; break;
case OCi.OP_EQ: tm = ltm.TMS.TM_EQ; break;
case OCi.OP_LT: tm = ltm.TMS.TM_LT; break;
case OCi.OP_LE: tm = ltm.TMS.TM_LE; break;
default:
return null; /* cannot find a reasonable name */
}
r.name = L.l_G.tmname[tm].getstr();
r.funcname = defs.to_luastring("metamethod", true);
return r;
};
const isinstack = function(L, ci, o) {
for (let i = ci.l_base; i < ci.top; i++) {
if (L.stack[i] === o)
return i;
}
return false;
};
/*
** Checks whether value 'o' came from an upvalue. (That can only happen
** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on
** upvalues.)
*/
const getupvalname = function(L, ci, o) {
let c = ci.func.value;
for (let i = 0; i < c.nupvalues; i++) {
if (c.upvals[i].v === o) {
return {
name: upvalname(c.p, i),
funcname: defs.to_luastring('upvalue', true)
};
}
}
return null;
};
const varinfo = function(L, o) {
let ci = L.ci;
let kind = null;
if (ci.callstatus & lstate.CIST_LUA) {
kind = getupvalname(L, ci, o); /* check whether 'o' is an upvalue */
let stkid = isinstack(L, ci, o);
if (!kind && stkid) /* no? try a register */
kind = getobjname(ci.func.value.p, currentpc(ci), stkid - ci.l_base);
}
return kind ? lobject.luaO_pushfstring(L, defs.to_luastring(" (%s '%s')", true), kind.funcname, kind.name) : defs.to_luastring("", true);
};
const luaG_typeerror = function(L, o, op) {
let t = ltm.luaT_objtypename(L, o);
luaG_runerror(L, defs.to_luastring("attempt to %s a %s value%s", true), op, t, varinfo(L, o));
};
const luaG_concaterror = function(L, p1, p2) {
if (p1.ttisstring() || lvm.cvt2str(p1)) p1 = p2;
luaG_typeerror(L, p1, defs.to_luastring('concatenate', true));
};
/*
** Error when both values are convertible to numbers, but not to integers
*/
const luaG_opinterror = function(L, p1, p2, msg) {
if (lvm.tonumber(p1) === false)
p2 = p1;
luaG_typeerror(L, p2, msg);
};
const luaG_ordererror = function(L, p1, p2) {
let t1 = ltm.luaT_objtypename(L, p1);
let t2 = ltm.luaT_objtypename(L, p2);
if (t1.join() === t2.join())
luaG_runerror(L, defs.to_luastring("attempt to compare two %s values", true), t1);
else
luaG_runerror(L, defs.to_luastring("attempt to compare %s with %s", true), t1, t2);
};
/* add src:line information to 'msg' */
const luaG_addinfo = function(L, msg, src, line) {
let buff;
if (src)
buff = lobject.luaO_chunkid(src.getstr(), luaconf.LUA_IDSIZE);
else
buff = ['?'.charCodeAt(0)];
return lobject.luaO_pushfstring(L, defs.to_luastring("%s:%d: %s", true), buff, line, msg);
};
const luaG_runerror = function(L, fmt, ...argp) {
let ci = L.ci;
let msg = lobject.luaO_pushvfstring(L, fmt, argp);
if (ci.callstatus & lstate.CIST_LUA) /* if Lua function, add source:line information */
luaG_addinfo(L, msg, ci.func.value.p.source, currentline(ci));
luaG_errormsg(L);
};
const luaG_errormsg = function(L) {
if (L.errfunc !== 0) { /* is there an error handling function? */
let errfunc = L.errfunc;
lobject.pushobj2s(L, L.stack[L.top - 1]); /* move argument */
lobject.setobjs2s(L, L.top - 2, errfunc); /* push function */
ldo.luaD_callnoyield(L, L.top - 2, 1);
}
ldo.luaD_throw(L, TS.LUA_ERRRUN);
};
/*
** Error when both values are convertible to numbers, but not to integers
*/
const luaG_tointerror = function(L, p1, p2) {
let temp = lvm.tointeger(p1);
if (temp === false)
p2 = p1;
luaG_runerror(L, defs.to_luastring("number%s has no integer representation", true), varinfo(L, p2));
};
const luaG_traceexec = function(L) {
let ci = L.ci;
let mask = L.hookmask;
let counthook = (--L.hookcount === 0 && (mask & defs.LUA_MASKCOUNT));
if (counthook)
L.hookcount = L.basehookcount; /* reset count */
else if (!(mask & defs.LUA_MASKLINE))
return; /* no line hook and count != 0; nothing to be done */
if (ci.callstatus & lstate.CIST_HOOKYIELD) { /* called hook last time? */
ci.callstatus &= ~lstate.CIST_HOOKYIELD; /* erase mark */
return; /* do not call hook again (VM yielded, so it did not move) */
}
if (counthook)
ldo.luaD_hook(L, defs.LUA_HOOKCOUNT, -1); /* call count hook */
if (mask & defs.LUA_MASKLINE) {
let p = ci.func.value.p;
let npc = ci.l_savedpc - 1; // pcRel(ci.u.l.savedpc, p);
let newline = p.lineinfo.length !== 0 ? p.lineinfo[npc] : -1;
if (npc === 0 || /* call linehook when enter a new function, */
ci.l_savedpc <= L.oldpc || /* when jump back (loop), or when */
newline !== (p.lineinfo.length !== 0 ? p.lineinfo[L.oldpc - 1] : -1)) /* enter a new line */
ldo.luaD_hook(L, defs.LUA_HOOKLINE, newline); /* call line hook */
}
L.oldpc = ci.l_savedpc;
if (L.status === TS.LUA_YIELD) { /* did hook yield? */
if (counthook)
L.hookcount = 1; /* undo decrement to zero */
ci.l_savedpc--; /* undo increment (resume will increment it again) */
ci.callstatus |= lstate.CIST_HOOKYIELD; /* mark that it yielded */
ci.funcOff = L.top - 1; /* protect stack below results */
ci.func = L.stack[ci.funcOff];
ldo.luaD_throw(L, TS.LUA_YIELD);
}
};
module.exports.luaG_addinfo = luaG_addinfo;
module.exports.luaG_concaterror = luaG_concaterror;
module.exports.luaG_errormsg = luaG_errormsg;
module.exports.luaG_opinterror = luaG_opinterror;
module.exports.luaG_ordererror = luaG_ordererror;
module.exports.luaG_runerror = luaG_runerror;
module.exports.luaG_tointerror = luaG_tointerror;
module.exports.luaG_traceexec = luaG_traceexec;
module.exports.luaG_typeerror = luaG_typeerror;
module.exports.lua_gethook = lua_gethook;
module.exports.lua_gethookcount = lua_gethookcount;
module.exports.lua_gethookmask = lua_gethookmask;
module.exports.lua_getinfo = lua_getinfo;
module.exports.lua_getlocal = lua_getlocal;
module.exports.lua_getstack = lua_getstack;
module.exports.lua_sethook = lua_sethook;
module.exports.lua_setlocal = lua_setlocal;
/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const lobject = __webpack_require__(5);
const CT = defs.constant_types;
class Proto {
constructor(L) {
this.id = L.l_G.id_counter++;
this.k = []; // constants used by the function
this.p = []; // functions defined inside the function
this.code = []; // opcodes
this.cache = null; // last-created closure with this prototype
this.lineinfo = []; // map from opcodes to source lines (debug information)
this.upvalues = []; // upvalue information
this.numparams = 0; // number of fixed parameters
this.is_vararg = false;
this.maxstacksize = 0; // number of registers needed by this function
this.locvars = []; // information about local variables (debug information)
this.linedefined = 0; // debug information
this.lastlinedefined = 0; // debug information
this.source = null; // used for debug information
}
}
class UpVal {
constructor(L) {
this.id = L.l_G.id_counter++;
this.v = void 0; /* if open: reference to TValue on stack. if closed: TValue */
this.vOff = void 0; /* if open: index on stack. if closed: undefined */
this.refcount = 0;
this.open_next = null; /* linked list (when open) */
}
isopen() {
return this.vOff !== void 0;
}
}
const luaF_newLclosure = function(L, n) {
let c = new lobject.LClosure(L, n);
return c;
};
const luaF_findupval = function(L, level) {
let prevp;
let p = L.openupval;
while (p !== null && p.vOff >= level) {
assert(p.isopen());
if (p.vOff === level) /* found a corresponding upvalue? */
return p; /* return it */
prevp = p;
p = p.open_next;
}
/* not found: create a new upvalue */
let uv = new UpVal(L);
/* link it to list of open upvalues */
uv.open_next = p;
if (prevp)
prevp.open_next = uv;
else
L.openupval = uv;
uv.v = L.stack[level]; /* current value lives in the stack */
uv.vOff = level;
return uv;
};
const luaF_close = function(L, level) {
while (L.openupval !== null && L.openupval.vOff >= level) {
let uv = L.openupval;
assert(uv.isopen());
L.openupval = uv.open_next; /* remove from 'open' list */
if (uv.refcount === 0) { /* no references? */
/* free upvalue */
uv.v = void 0;
uv.open_next = null;
} else {
let from = uv.v;
uv.v = new lobject.TValue(from.type, from.value);
}
uv.vOff = void 0;
}
};
/*
** fill a closure with new closed upvalues
*/
const luaF_initupvals = function(L, cl) {
for (let i = 0; i < cl.nupvalues; i++) {
let uv = new UpVal(L);
uv.refcount = 1;
uv.v = new lobject.TValue(CT.LUA_TNIL, null);
cl.upvals[i] = uv;
}
};
/*
** Look for n-th local variable at line 'line' in function 'func'.
** Returns null if not found.
*/
const luaF_getlocalname = function(f, local_number, pc) {
for (let i = 0; i < f.locvars.length && f.locvars[i].startpc <= pc; i++) {
if (pc < f.locvars[i].endpc) { /* is variable active? */
local_number--;
if (local_number === 0)
return f.locvars[i].varname.getstr();
}
}
return null; /* not found */
};
module.exports.MAXUPVAL = 255;
module.exports.Proto = Proto;
module.exports.UpVal = UpVal;
module.exports.luaF_findupval = luaF_findupval;
module.exports.luaF_close = luaF_close;
module.exports.luaF_getlocalname = luaF_getlocalname;
module.exports.luaF_initupvals = luaF_initupvals;
module.exports.luaF_newLclosure = luaF_newLclosure;
/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const lobject = __webpack_require__(5);
const ldo = __webpack_require__(12);
const lapi = __webpack_require__(37);
const ltable = __webpack_require__(14);
const lfunc = __webpack_require__(20);
const ltm = __webpack_require__(26);
const CT = defs.constant_types;
const TS = defs.thread_status;
const LUA_NUMTAGS = CT.LUA_NUMTAGS;
const EXTRA_STACK = 5;
const BASIC_STACK_SIZE = 2 * defs.LUA_MINSTACK;
class CallInfo {
constructor() {
this.func = null;
this.funcOff = NaN;
this.top = NaN;
this.previous = null;
this.next = null;
/* only for Lua functions */
this.l_base = NaN; /* base for this function */
this.l_code = null; /* reference to this.func.p.code */
this.l_savedpc = NaN; /* offset into l_code */
/* only for JS functions */
this.c_k = null; /* continuation in case of yields */
this.c_old_errfunc = null;
this.c_ctx = null; /* context info. in case of yields */
this.nresults = NaN;
this.callstatus = NaN;
}
}
class lua_State {
constructor(g) {
this.id = g.id_counter++;
this.base_ci = new CallInfo(); /* CallInfo for first level (C calling Lua) */
this.top = NaN; /* first free slot in the stack */
this.stack_last = NaN; /* last free slot in the stack */
this.oldpc = NaN; /* last pc traced */
/* preinit_thread */
this.l_G = g;
this.stack = null;
this.ci = null;
this.errorJmp = null;
this.nCcalls = 0;
this.hook = null;
this.hookmask = 0;
this.basehookcount = 0;
this.allowhook = 1;
this.hookcount = this.basehookcount;
this.openupval = null;
this.nny = 1;
this.status = TS.LUA_OK;
this.errfunc = 0;
}
}
class global_State {
constructor() {
this.id_counter = 0; /* used to give objects unique ids */
this.mainthread = null;
this.l_registry = new lobject.TValue(CT.LUA_TNIL, null);
this.panic = null;
this.atnativeerror = null;
this.version = null;
this.tmname = new Array(ltm.TMS.TM_N);
this.mt = new Array(LUA_NUMTAGS);
}
}
const luaE_extendCI = function(L) {
let ci = new CallInfo();
L.ci.next = ci;
ci.previous = L.ci;
ci.next = null;
L.ci = ci;
return ci;
};
const luaE_freeCI = function(L) {
let ci = L.ci;
ci.next = null;
};
const stack_init = function(L1, L) {
L1.stack = new Array(BASIC_STACK_SIZE);
L1.top = 0;
L1.stack_last = BASIC_STACK_SIZE - EXTRA_STACK;
/* initialize first ci */
let ci = L1.base_ci;
ci.next = ci.previous = null;
ci.callstatus = 0;
ci.funcOff = L1.top;
ci.func = L1.stack[L1.top];
L1.stack[L1.top++] = new lobject.TValue(CT.LUA_TNIL, null);
ci.top = L1.top + defs.LUA_MINSTACK;
L1.ci = ci;
};
const freestack = function(L) {
L.ci = L.base_ci;
luaE_freeCI(L);
L.stack = null;
};
/*
** Create registry table and its predefined values
*/
const init_registry = function(L, g) {
let registry = ltable.luaH_new(L);
g.l_registry.sethvalue(registry);
ltable.luaH_setint(registry, defs.LUA_RIDX_MAINTHREAD, new lobject.TValue(CT.LUA_TTHREAD, L));
ltable.luaH_setint(registry, defs.LUA_RIDX_GLOBALS, new lobject.TValue(CT.LUA_TTABLE, ltable.luaH_new(L)));
};
/*
** open parts of the state that may cause memory-allocation errors.
** ('g->version' !== NULL flags that the state was completely build)
*/
const f_luaopen = function(L) {
let g = L.l_G;
stack_init(L, L);
init_registry(L, g);
ltm.luaT_init(L);
g.version = lapi.lua_version(null);
};
const lua_newthread = function(L) {
let g = L.l_G;
let L1 = new lua_State(g);
L.stack[L.top] = new lobject.TValue(CT.LUA_TTHREAD, L1);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
L1.hookmask = L.hookmask;
L1.basehookcount = L.basehookcount;
L1.hook = L.hook;
L1.hookcount = L1.basehookcount;
stack_init(L1, L);
return L1;
};
const luaE_freethread = function(L, L1) {
lfunc.luaF_close(L1, L1.stack);
freestack(L1);
};
const lua_newstate = function() {
let g = new global_State();
let L = new lua_State(g);
g.mainthread = L;
if (ldo.luaD_rawrunprotected(L, f_luaopen, null) !== TS.LUA_OK) {
L = null;
}
return L;
};
const close_state = function(L) {
lfunc.luaF_close(L, L.stack); /* close all upvalues for this thread */
freestack(L);
};
const lua_close = function(L) {
L = L.l_G.mainthread; /* only the main thread can be closed */
close_state(L);
};
module.exports.lua_State = lua_State;
module.exports.CallInfo = CallInfo;
module.exports.CIST_OAH = (1<<0); /* original value of 'allowhook' */
module.exports.CIST_LUA = (1<<1); /* call is running a Lua function */
module.exports.CIST_HOOKED = (1<<2); /* call is running a debug hook */
module.exports.CIST_FRESH = (1<<3); /* call is running on a fresh invocation of luaV_execute */
module.exports.CIST_YPCALL = (1<<4); /* call is a yieldable protected call */
module.exports.CIST_TAIL = (1<<5); /* call was tail called */
module.exports.CIST_HOOKYIELD = (1<<6); /* last hook called yielded */
module.exports.CIST_LEQ = (1<<7); /* using __lt for __le */
module.exports.CIST_FIN = (1<<8); /* call is running a finalizer */
module.exports.EXTRA_STACK = EXTRA_STACK;
module.exports.lua_close = lua_close;
module.exports.lua_newstate = lua_newstate;
module.exports.lua_newthread = lua_newthread;
module.exports.luaE_extendCI = luaE_extendCI;
module.exports.luaE_freeCI = luaE_freeCI;
module.exports.luaE_freethread = luaE_freethread;
/***/ }),
/* 22 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const llimit = __webpack_require__(10);
const sprintf = __webpack_require__(34).sprintf;
/*
@@ LUAI_MAXSTACK limits the size of the Lua stack.
** CHANGE it if you need a different limit. This limit is arbitrary;
** its only purpose is to stop Lua from consuming unlimited stack
** space (and to reserve some numbers for pseudo-indices).
*/
/* TODO: put back to 1000000. Node would go out of memory in some cases (e.g. travis) */
const LUAI_MAXSTACK = 100000;
/*
@@ LUA_IDSIZE gives the maximum size for the description of the source
@@ of a function in debug information.
** CHANGE it if you want a different size.
*/
const LUA_IDSIZE = 60;
const lua_integer2str = function(n) {
return sprintf(LUA_INTEGER_FMT, n);
};
const lua_number2str = function(n) {
return sprintf(LUA_NUMBER_FMT, n);
};
const lua_numbertointeger = function(n) {
return n >= llimit.MIN_INT && n < -llimit.MIN_INT ? n : false;
};
const LUA_INTEGER_FRMLEN = "";
const LUA_NUMBER_FRMLEN = "";
const LUA_INTEGER_FMT = `%${LUA_INTEGER_FRMLEN}d`;
const LUA_NUMBER_FMT = "%.14g";
const lua_getlocaledecpoint = function() {
return (1.1).toLocaleString().substring(1, 2);
};
// See: http://croquetweak.blogspot.fr/2014/08/deconstructing-floats-frexp-and-ldexp.html
const frexp = function(value) {
if (value === 0) return [value, 0];
var data = new DataView(new ArrayBuffer(8));
data.setFloat64(0, value);
var bits = (data.getUint32(0) >>> 20) & 0x7FF;
if (bits === 0) { // denormal
data.setFloat64(0, value * Math.pow(2, 64)); // exp + 64
bits = ((data.getUint32(0) >>> 20) & 0x7FF) - 64;
}
var exponent = bits - 1022;
var mantissa = ldexp(value, -exponent);
return [mantissa, exponent];
};
const ldexp = function(mantissa, exponent) {
var steps = Math.min(3, Math.ceil(Math.abs(exponent) / 1023));
var result = mantissa;
for (var i = 0; i < steps; i++)
result *= Math.pow(2, Math.floor((exponent + i) / steps));
return result;
};
module.exports.frexp = frexp;
module.exports.ldexp = ldexp;
module.exports.LUAI_MAXSTACK = LUAI_MAXSTACK;
module.exports.LUA_IDSIZE = LUA_IDSIZE;
module.exports.LUA_INTEGER_FMT = LUA_INTEGER_FMT;
module.exports.LUA_INTEGER_FRMLEN = LUA_INTEGER_FRMLEN;
module.exports.LUA_NUMBER_FMT = LUA_NUMBER_FMT;
module.exports.LUA_NUMBER_FRMLEN = LUA_NUMBER_FRMLEN;
module.exports.lua_getlocaledecpoint = lua_getlocaledecpoint;
module.exports.lua_integer2str = lua_integer2str;
module.exports.lua_number2str = lua_number2str;
module.exports.lua_numbertointeger = lua_numbertointeger;
/***/ }),
/* 23 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const ldo = __webpack_require__(13);
const lfunc = __webpack_require__(24);
const lobject = __webpack_require__(7);
const lopcodes = __webpack_require__(33);
const lstate = __webpack_require__(25);
const ltable = __webpack_require__(16);
const ltm = __webpack_require__(31);
const luaconf = __webpack_require__(22);
const lvm = __webpack_require__(32);
const CT = defs.constant_types;
const TS = defs.thread_status;
const currentpc = function(ci) {
assert(ci.callstatus & lstate.CIST_LUA);
return ci.l_savedpc - 1;
};
const currentline = function(ci) {
return ci.func.value.p.lineinfo.length !== 0 ? ci.func.value.p.lineinfo[currentpc(ci)] : -1;
};
/*
** If function yielded, its 'func' can be in the 'extra' field. The
** next function restores 'func' to its correct value for debugging
** purposes. (It exchanges 'func' and 'extra'; so, when called again,
** after debugging, it also "re-restores" ** 'func' to its altered value.
*/
const swapextra = function(L) {
if (L.status === TS.LUA_YIELD) {
let ci = L.ci; /* get function that yielded */
let temp = ci.funcOff; /* exchange its 'func' and 'extra' values */
ci.func = L.stack[ci.extra];
ci.funcOff = ci.extra;
ci.extra = temp;
}
};
const lua_sethook = function(L, func, mask, count) {
if (func === null || mask === 0) { /* turn off hooks? */
mask = 0;
func = null;
}
if (L.ci.callstatus & lstate.CIST_LUA)
L.oldpc = L.ci.l_savedpc;
L.hook = func;
L.basehookcount = count;
L.hookcount = L.basehookcount;
L.hookmask = mask;
};
const lua_gethook = function(L) {
return L.hook;
};
const lua_gethookmask = function(L) {
return L.hookmask;
};
const lua_gethookcount = function(L) {
return L.basehookcount;
};
const lua_getstack = function(L, level, ar) {
let ci;
let status;
if (level < 0) return 0; /* invalid (negative) level */
for (ci = L.ci; level > 0 && ci !== L.base_ci; ci = ci.previous)
level--;
if (level === 0 && ci !== L.base_ci) { /* level found? */
status = 1;
ar.i_ci = ci;
} else
status = 0; /* no such level */
return status;
};
const upvalname = function(p, uv) {
assert(uv < p.upvalues.length);
let s = p.upvalues[uv].name;
if (s === null) return ["?".charCodeAt(0)];
return s.getstr();
};
const findvararg = function(ci, n) {
let nparams = ci.func.value.p.numparams;
if (n >= ci.l_base - ci.funcOff - nparams)
return null; /* no such vararg */
else {
return {
pos: ci.funcOff + nparams + n,
name: defs.to_luastring("(*vararg)", true) /* generic name for any vararg */
};
}
};
const findlocal = function(L, ci, n) {
let base, name = null;
if (ci.callstatus & lstate.CIST_LUA) {
if (n < 0) /* access to vararg values? */
return findvararg(ci, -n);
else {
base = ci.l_base;
name = lfunc.luaF_getlocalname(ci.func.value.p, n, currentpc(ci));
}
} else
base = ci.funcOff + 1;
if (name === null) { /* no 'standard' name? */
let limit = ci === L.ci ? L.top : ci.next.funcOff;
if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
name = defs.to_luastring("(*temporary)", true); /* generic name for any valid slot */
else
return null; /* no name */
}
return {
pos: base + (n - 1),
name: name
};
};
const lua_getlocal = function(L, ar, n) {
let name;
swapextra(L);
if (ar === null) { /* information about non-active function? */
if (!L.stack[L.top - 1].ttisLclosure()) /* not a Lua function? */
name = null;
else /* consider live variables at function start (parameters) */
name = lfunc.luaF_getlocalname(L.stack[L.top - 1].value.p, n, 0);
} else { /* active function; get information through 'ar' */
let local = findlocal(L, ar.i_ci, n);
if (local) {
name = local.name;
lobject.pushobj2s(L, L.stack[local.pos]);
assert(L.top <= L.ci.top, "stack overflow");
} else {
name = null;
}
}
swapextra(L);
return name;
};
const lua_setlocal = function(L, ar, n) {
let name;
swapextra(L);
let local = findlocal(L, ar.i_ci, n);
if (local) {
name = local.name;
lobject.setobjs2s(L, local.pos, L.top - 1);
delete L.stack[--L.top]; /* pop value */
} else {
name = null;
}
swapextra(L);
return name;
};
const funcinfo = function(ar, cl) {
if (cl === null || cl instanceof lobject.CClosure) {
ar.source = defs.to_luastring("=[JS]", true);
ar.linedefined = -1;
ar.lastlinedefined = -1;
ar.what = ["J".charCodeAt(0)];
} else {
let p = cl.p;
ar.source = p.source ? p.source.getstr() : defs.to_luastring("=?", true);
ar.linedefined = p.linedefined;
ar.lastlinedefined = p.lastlinedefined;
ar.what = ar.linedefined === 0 ? defs.to_luastring("main", true) : defs.to_luastring("Lua", true);
}
ar.short_src = lobject.luaO_chunkid(ar.source, luaconf.LUA_IDSIZE);
};
const collectvalidlines = function(L, f) {
if (f === null || f instanceof lobject.CClosure) {
L.stack[L.top] = new lobject.TValue(CT.LUA_TNIL, null);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
} else {
let lineinfo = f.p.lineinfo;
let t = ltable.luaH_new(L);
L.stack[L.top] = new lobject.TValue(CT.LUA_TTABLE, t);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
let v = new lobject.TValue(CT.LUA_TBOOLEAN, true);
for (let i = 0; i < lineinfo.length; i++)
ltable.luaH_setint(t, lineinfo[i], v);
}
};
const getfuncname = function(L, ci) {
let r = {
name: null,
funcname: null
};
if (ci === null)
return null;
else if (ci.callstatus & lstate.CIST_FIN) { /* is this a finalizer? */
r.name = defs.to_luastring("__gc", true);
r.funcname = defs.to_luastring("metamethod", true); /* report it as such */
return r;
}
/* calling function is a known Lua function? */
else if (!(ci.callstatus & lstate.CIST_TAIL) && ci.previous.callstatus & lstate.CIST_LUA)
return funcnamefromcode(L, ci.previous);
else return null; /* no way to find a name */
};
const auxgetinfo = function(L, what, ar, f, ci) {
let status = 1;
for (; what.length > 0; what = what.slice(1)) {
switch (String.fromCharCode(what[0])) {
case 'S': {
funcinfo(ar, f);
break;
}
case 'l': {
ar.currentline = ci && ci.callstatus & lstate.CIST_LUA ? currentline(ci) : -1;
break;
}
case 'u': {
ar.nups = f === null ? 0 : f.nupvalues;
if (f === null || f instanceof lobject.CClosure) {
ar.isvararg = true;
ar.nparams = 0;
} else {
ar.isvararg = f.p.is_vararg;
ar.nparams = f.p.numparams;
}
break;
}
case 't': {
ar.istailcall = ci ? ci.callstatus & lstate.CIST_TAIL : 0;
break;
}
case 'n': {
let r = getfuncname(L, ci);
if (r === null) {
ar.namewhat = [];
ar.name = null;
} else {
ar.namewhat = r.funcname;
ar.name = r.name;
}
break;
}
case 'L':
case 'f': /* handled by lua_getinfo */
break;
default: status = 0; /* invalid option */
}
}
return status;
};
const lua_getinfo = function(L, what, ar) {
let status, cl, ci, func;
swapextra(L);
if (what[0] === '>'.charCodeAt(0)) {
ci = null;
func = L.stack[L.top - 1];
assert(L, func.ttisfunction(), "function expected");
what = what.slice(1); /* skip the '>' */
L.top--; /* pop function */
} else {
ci = ar.i_ci;
func = ci.func;
assert(ci.func.ttisfunction());
}
cl = func.ttisclosure() ? func.value : null;
status = auxgetinfo(L, what, ar, cl, ci);
if (what.indexOf('f'.charCodeAt(0)) >= 0) {
lobject.pushobj2s(L, func);
assert(L.top <= L.ci.top, "stack overflow");
}
swapextra(L);
if (what.indexOf('L'.charCodeAt(0)) >= 0)
collectvalidlines(L, cl);
return status;
};
const kname = function(p, pc, c) {
let r = {
name: null,
funcname: null
};
if (lopcodes.ISK(c)) { /* is 'c' a constant? */
let kvalue = p.k[lopcodes.INDEXK(c)];
if (kvalue.ttisstring()) { /* literal constant? */
r.name = kvalue.svalue(); /* it is its own name */
return r;
}
/* else no reasonable name found */
} else { /* 'c' is a register */
let what = getobjname(p, pc, c); /* search for 'c' */
if (what && what.funcname[0] === 'c'.charCodeAt(0)) { /* found a constant name? */
return what; /* 'name' already filled */
}
/* else no reasonable name found */
}
r.name = [defs.char["?"]];
return r; /* no reasonable name found */
};
const filterpc = function(pc, jmptarget) {
if (pc < jmptarget) /* is code conditional (inside a jump)? */
return -1; /* cannot know who sets that register */
else return pc; /* current position sets that register */
};
/*
** try to find last instruction before 'lastpc' that modified register 'reg'
*/
const findsetreg = function(p, lastpc, reg) {
let setreg = -1; /* keep last instruction that changed 'reg' */
let jmptarget = 0; /* any code before this address is conditional */
let OCi = lopcodes.OpCodesI;
for (let pc = 0; pc < lastpc; pc++) {
let i = p.code[pc];
let a = i.A;
switch (i.opcode) {
case OCi.OP_LOADNIL: {
let b = i.B;
if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
setreg = filterpc(pc, jmptarget);
break;
}
case OCi.OP_TFORCALL: {
if (reg >= a + 2) /* affect all regs above its base */
setreg = filterpc(pc, jmptarget);
break;
}
case OCi.OP_CALL:
case OCi.OP_TAILCALL: {
if (reg >= a) /* affect all registers above base */
setreg = filterpc(pc, jmptarget);
break;
}
case OCi.OP_JMP: {
let b = i.sBx;
let dest = pc + 1 + b;
/* jump is forward and do not skip 'lastpc'? */
if (pc < dest && dest <= lastpc) {
if (dest > jmptarget)
jmptarget = dest; /* update 'jmptarget' */
}
break;
}
default:
if (lopcodes.testAMode(i.opcode) && reg === a)
setreg = filterpc(pc, jmptarget);
break;
}
}
return setreg;
};
const getobjname = function(p, lastpc, reg) {
let r = {
name: lfunc.luaF_getlocalname(p, reg + 1, lastpc),
funcname: null
};
if (r.name) { /* is a local? */
r.funcname = defs.to_luastring("local", true);
return r;
}
/* else try symbolic execution */
let pc = findsetreg(p, lastpc, reg);
let OCi = lopcodes.OpCodesI;
if (pc !== -1) { /* could find instruction? */
let i = p.code[pc];
switch (i.opcode) {
case OCi.OP_MOVE: {
let b = i.B; /* move from 'b' to 'a' */
if (b < i.A)
return getobjname(p, pc, b); /* get name for 'b' */
break;
}
case OCi.OP_GETTABUP:
case OCi.OP_GETTABLE: {
let k = i.C; /* key index */
let t = i.B; /* table index */
let vn = i.opcode === OCi.OP_GETTABLE ? lfunc.luaF_getlocalname(p, t + 1, pc) : upvalname(p, t);
r.name = kname(p, pc, k).name;
r.funcname = vn && defs.to_jsstring(vn) === "_ENV" ? defs.to_luastring("global", true) : defs.to_luastring("field", true);
return r;
}
case OCi.OP_GETUPVAL: {
r.name = upvalname(p, i.B);
r.funcname = defs.to_luastring("upvalue", true);
return r;
}
case OCi.OP_LOADK:
case OCi.OP_LOADKX: {
let b = i.opcode === OCi.OP_LOADK ? i.Bx : p.code[pc + 1].Ax;
if (p.k[b].ttisstring()) {
r.name = p.k[b].svalue();
r.funcname = defs.to_luastring("constant", true);
return r;
}
break;
}
case OCi.OP_SELF: {
let k = i.C;
r.name = kname(p, pc, k).name;
r.funcname = defs.to_luastring("method", true);
return r;
}
default: break;
}
}
return null;
};
/*
** Try to find a name for a function based on the code that called it.
** (Only works when function was called by a Lua function.)
** Returns what the name is (e.g., "for iterator", "method",
** "metamethod") and sets '*name' to point to the name.
*/
const funcnamefromcode = function(L, ci) {
let r = {
name: null,
funcname: null
};
let tm = 0; /* (initial value avoids warnings) */
let p = ci.func.value.p; /* calling function */
let pc = currentpc(ci); /* calling instruction index */
let i = p.code[pc]; /* calling instruction */
let OCi = lopcodes.OpCodesI;
if (ci.callstatus & lstate.CIST_HOOKED) {
r.name = [defs.char["?"]];
r.funcname = defs.to_luastring("hook", true);
return r;
}
switch (i.opcode) {
case OCi.OP_CALL:
case OCi.OP_TAILCALL:
return getobjname(p, pc, i.A); /* get function name */
case OCi.OP_TFORCALL:
r.name = defs.to_luastring("for iterator", true);
r.funcname = defs.to_luastring("for iterator", true);
return r;
/* other instructions can do calls through metamethods */
case OCi.OP_SELF:
case OCi.OP_GETTABUP:
case OCi.OP_GETTABLE:
tm = ltm.TMS.TM_INDEX;
break;
case OCi.OP_SETTABUP:
case OCi.OP_SETTABLE:
tm = ltm.TMS.TM_NEWINDEX;
break;
case OCi.OP_ADD: tm = ltm.TMS.TM_ADD; break;
case OCi.OP_SUB: tm = ltm.TMS.TM_SUB; break;
case OCi.OP_MUL: tm = ltm.TMS.TM_MUL; break;
case OCi.OP_MOD: tm = ltm.TMS.TM_MOD; break;
case OCi.OP_POW: tm = ltm.TMS.TM_POW; break;
case OCi.OP_DIV: tm = ltm.TMS.TM_DIV; break;
case OCi.OP_IDIV: tm = ltm.TMS.TM_IDIV; break;
case OCi.OP_BAND: tm = ltm.TMS.TM_BAND; break;
case OCi.OP_BOR: tm = ltm.TMS.TM_BOR; break;
case OCi.OP_BXOR: tm = ltm.TMS.TM_BXOR; break;
case OCi.OP_SHL: tm = ltm.TMS.TM_SHL; break;
case OCi.OP_SHR: tm = ltm.TMS.TM_SHR; break;
case OCi.OP_UNM: tm = ltm.TMS.TM_UNM; break;
case OCi.OP_BNOT: tm = ltm.TMS.TM_BNOT; break;
case OCi.OP_LEN: tm = ltm.TMS.TM_LEN; break;
case OCi.OP_CONCAT: tm = ltm.TMS.TM_CONCAT; break;
case OCi.OP_EQ: tm = ltm.TMS.TM_EQ; break;
case OCi.OP_LT: tm = ltm.TMS.TM_LT; break;
case OCi.OP_LE: tm = ltm.TMS.TM_LE; break;
default:
return null; /* cannot find a reasonable name */
}
r.name = L.l_G.tmname[tm].getstr();
r.funcname = defs.to_luastring("metamethod", true);
return r;
};
const isinstack = function(L, ci, o) {
for (let i = ci.l_base; i < ci.top; i++) {
if (L.stack[i] === o)
return i;
}
return false;
};
/*
** Checks whether value 'o' came from an upvalue. (That can only happen
** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on
** upvalues.)
*/
const getupvalname = function(L, ci, o) {
let c = ci.func.value;
for (let i = 0; i < c.nupvalues; i++) {
if (c.upvals[i].v === o) {
return {
name: upvalname(c.p, i),
funcname: defs.to_luastring('upvalue', true)
};
}
}
return null;
};
const varinfo = function(L, o) {
let ci = L.ci;
let kind = null;
if (ci.callstatus & lstate.CIST_LUA) {
kind = getupvalname(L, ci, o); /* check whether 'o' is an upvalue */
let stkid = isinstack(L, ci, o);
if (!kind && stkid) /* no? try a register */
kind = getobjname(ci.func.value.p, currentpc(ci), stkid - ci.l_base);
}
return kind ? lobject.luaO_pushfstring(L, defs.to_luastring(" (%s '%s')", true), kind.funcname, kind.name) : defs.to_luastring("", true);
};
const luaG_typeerror = function(L, o, op) {
let t = ltm.luaT_objtypename(L, o);
luaG_runerror(L, defs.to_luastring("attempt to %s a %s value%s", true), op, t, varinfo(L, o));
};
const luaG_concaterror = function(L, p1, p2) {
if (p1.ttisstring() || lvm.cvt2str(p1)) p1 = p2;
luaG_typeerror(L, p1, defs.to_luastring('concatenate', true));
};
/*
** Error when both values are convertible to numbers, but not to integers
*/
const luaG_opinterror = function(L, p1, p2, msg) {
if (lvm.tonumber(p1) === false)
p2 = p1;
luaG_typeerror(L, p2, msg);
};
const luaG_ordererror = function(L, p1, p2) {
let t1 = ltm.luaT_objtypename(L, p1);
let t2 = ltm.luaT_objtypename(L, p2);
if (t1.join() === t2.join())
luaG_runerror(L, defs.to_luastring("attempt to compare two %s values", true), t1);
else
luaG_runerror(L, defs.to_luastring("attempt to compare %s with %s", true), t1, t2);
};
/* add src:line information to 'msg' */
const luaG_addinfo = function(L, msg, src, line) {
let buff;
if (src)
buff = lobject.luaO_chunkid(src.getstr(), luaconf.LUA_IDSIZE);
else
buff = ['?'.charCodeAt(0)];
return lobject.luaO_pushfstring(L, defs.to_luastring("%s:%d: %s", true), buff, line, msg);
};
const luaG_runerror = function(L, fmt, ...argp) {
let ci = L.ci;
let msg = lobject.luaO_pushvfstring(L, fmt, argp);
if (ci.callstatus & lstate.CIST_LUA) /* if Lua function, add source:line information */
luaG_addinfo(L, msg, ci.func.value.p.source, currentline(ci));
luaG_errormsg(L);
};
const luaG_errormsg = function(L) {
if (L.errfunc !== 0) { /* is there an error handling function? */
let errfunc = L.errfunc;
lobject.pushobj2s(L, L.stack[L.top - 1]); /* move argument */
lobject.setobjs2s(L, L.top - 2, errfunc); /* push function */
ldo.luaD_callnoyield(L, L.top - 2, 1);
}
ldo.luaD_throw(L, TS.LUA_ERRRUN);
};
/*
** Error when both values are convertible to numbers, but not to integers
*/
const luaG_tointerror = function(L, p1, p2) {
let temp = lvm.tointeger(p1);
if (temp === false)
p2 = p1;
luaG_runerror(L, defs.to_luastring("number%s has no integer representation", true), varinfo(L, p2));
};
const luaG_traceexec = function(L) {
let ci = L.ci;
let mask = L.hookmask;
let counthook = (--L.hookcount === 0 && (mask & defs.LUA_MASKCOUNT));
if (counthook)
L.hookcount = L.basehookcount; /* reset count */
else if (!(mask & defs.LUA_MASKLINE))
return; /* no line hook and count != 0; nothing to be done */
if (ci.callstatus & lstate.CIST_HOOKYIELD) { /* called hook last time? */
ci.callstatus &= ~lstate.CIST_HOOKYIELD; /* erase mark */
return; /* do not call hook again (VM yielded, so it did not move) */
}
if (counthook)
ldo.luaD_hook(L, defs.LUA_HOOKCOUNT, -1); /* call count hook */
if (mask & defs.LUA_MASKLINE) {
let p = ci.func.value.p;
let npc = ci.l_savedpc - 1; // pcRel(ci.u.l.savedpc, p);
let newline = p.lineinfo.length !== 0 ? p.lineinfo[npc] : -1;
if (npc === 0 || /* call linehook when enter a new function, */
ci.l_savedpc <= L.oldpc || /* when jump back (loop), or when */
newline !== (p.lineinfo.length !== 0 ? p.lineinfo[L.oldpc - 1] : -1)) /* enter a new line */
ldo.luaD_hook(L, defs.LUA_HOOKLINE, newline); /* call line hook */
}
L.oldpc = ci.l_savedpc;
if (L.status === TS.LUA_YIELD) { /* did hook yield? */
if (counthook)
L.hookcount = 1; /* undo decrement to zero */
ci.l_savedpc--; /* undo increment (resume will increment it again) */
ci.callstatus |= lstate.CIST_HOOKYIELD; /* mark that it yielded */
ci.funcOff = L.top - 1; /* protect stack below results */
ci.func = L.stack[ci.funcOff];
ldo.luaD_throw(L, TS.LUA_YIELD);
}
};
module.exports.luaG_addinfo = luaG_addinfo;
module.exports.luaG_concaterror = luaG_concaterror;
module.exports.luaG_errormsg = luaG_errormsg;
module.exports.luaG_opinterror = luaG_opinterror;
module.exports.luaG_ordererror = luaG_ordererror;
module.exports.luaG_runerror = luaG_runerror;
module.exports.luaG_tointerror = luaG_tointerror;
module.exports.luaG_traceexec = luaG_traceexec;
module.exports.luaG_typeerror = luaG_typeerror;
module.exports.lua_gethook = lua_gethook;
module.exports.lua_gethookcount = lua_gethookcount;
module.exports.lua_gethookmask = lua_gethookmask;
module.exports.lua_getinfo = lua_getinfo;
module.exports.lua_getlocal = lua_getlocal;
module.exports.lua_getstack = lua_getstack;
module.exports.lua_sethook = lua_sethook;
module.exports.lua_setlocal = lua_setlocal;
/***/ }),
/* 24 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const lobject = __webpack_require__(7);
const CT = defs.constant_types;
class Proto {
constructor(L) {
this.id = L.l_G.id_counter++;
this.k = []; // constants used by the function
this.p = []; // functions defined inside the function
this.code = []; // opcodes
this.cache = null; // last-created closure with this prototype
this.lineinfo = []; // map from opcodes to source lines (debug information)
this.upvalues = []; // upvalue information
this.numparams = 0; // number of fixed parameters
this.is_vararg = false;
this.maxstacksize = 0; // number of registers needed by this function
this.locvars = []; // information about local variables (debug information)
this.linedefined = 0; // debug information
this.lastlinedefined = 0; // debug information
this.source = null; // used for debug information
}
}
class UpVal {
constructor(L) {
this.id = L.l_G.id_counter++;
this.v = void 0; /* if open: reference to TValue on stack. if closed: TValue */
this.vOff = void 0; /* if open: index on stack. if closed: undefined */
this.refcount = 0;
this.open_next = null; /* linked list (when open) */
}
isopen() {
return this.vOff !== void 0;
}
}
const luaF_newLclosure = function(L, n) {
let c = new lobject.LClosure(L, n);
return c;
};
const luaF_findupval = function(L, level) {
let prevp;
let p = L.openupval;
while (p !== null && p.vOff >= level) {
assert(p.isopen());
if (p.vOff === level) /* found a corresponding upvalue? */
return p; /* return it */
prevp = p;
p = p.open_next;
}
/* not found: create a new upvalue */
let uv = new UpVal(L);
/* link it to list of open upvalues */
uv.open_next = p;
if (prevp)
prevp.open_next = uv;
else
L.openupval = uv;
uv.v = L.stack[level]; /* current value lives in the stack */
uv.vOff = level;
return uv;
};
const luaF_close = function(L, level) {
while (L.openupval !== null && L.openupval.vOff >= level) {
let uv = L.openupval;
assert(uv.isopen());
L.openupval = uv.open_next; /* remove from 'open' list */
if (uv.refcount === 0) { /* no references? */
/* free upvalue */
uv.v = void 0;
uv.open_next = null;
} else {
let from = uv.v;
uv.v = new lobject.TValue(from.type, from.value);
}
uv.vOff = void 0;
}
};
/*
** fill a closure with new closed upvalues
*/
const luaF_initupvals = function(L, cl) {
for (let i = 0; i < cl.nupvalues; i++) {
let uv = new UpVal(L);
uv.refcount = 1;
uv.v = new lobject.TValue(CT.LUA_TNIL, null);
cl.upvals[i] = uv;
}
};
/*
** Look for n-th local variable at line 'line' in function 'func'.
** Returns null if not found.
*/
const luaF_getlocalname = function(f, local_number, pc) {
for (let i = 0; i < f.locvars.length && f.locvars[i].startpc <= pc; i++) {
if (pc < f.locvars[i].endpc) { /* is variable active? */
local_number--;
if (local_number === 0)
return f.locvars[i].varname.getstr();
}
}
return null; /* not found */
};
module.exports.MAXUPVAL = 255;
module.exports.Proto = Proto;
module.exports.UpVal = UpVal;
module.exports.luaF_findupval = luaF_findupval;
module.exports.luaF_close = luaF_close;
module.exports.luaF_getlocalname = luaF_getlocalname;
module.exports.luaF_initupvals = luaF_initupvals;
module.exports.luaF_newLclosure = luaF_newLclosure;
/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const lobject = __webpack_require__(7);
const ldo = __webpack_require__(13);
const lapi = __webpack_require__(38);
const ltable = __webpack_require__(16);
const lfunc = __webpack_require__(24);
const ltm = __webpack_require__(31);
const CT = defs.constant_types;
const TS = defs.thread_status;
const LUA_NUMTAGS = CT.LUA_NUMTAGS;
const EXTRA_STACK = 5;
const BASIC_STACK_SIZE = 2 * defs.LUA_MINSTACK;
class CallInfo {
constructor() {
this.func = null;
this.funcOff = NaN;
this.top = NaN;
this.previous = null;
this.next = null;
/* only for Lua functions */
this.l_base = NaN; /* base for this function */
this.l_code = null; /* reference to this.func.p.code */
this.l_savedpc = NaN; /* offset into l_code */
/* only for JS functions */
this.c_k = null; /* continuation in case of yields */
this.c_old_errfunc = null;
this.c_ctx = null; /* context info. in case of yields */
this.nresults = NaN;
this.callstatus = NaN;
}
}
class lua_State {
constructor(g) {
this.id = g.id_counter++;
this.base_ci = new CallInfo(); /* CallInfo for first level (C calling Lua) */
this.top = NaN; /* first free slot in the stack */
this.stack_last = NaN; /* last free slot in the stack */
this.oldpc = NaN; /* last pc traced */
/* preinit_thread */
this.l_G = g;
this.stack = null;
this.ci = null;
this.errorJmp = null;
this.nCcalls = 0;
this.hook = null;
this.hookmask = 0;
this.basehookcount = 0;
this.allowhook = 1;
this.hookcount = this.basehookcount;
this.openupval = null;
this.nny = 1;
this.status = TS.LUA_OK;
this.errfunc = 0;
}
}
class global_State {
constructor() {
this.id_counter = 0; /* used to give objects unique ids */
this.mainthread = null;
this.l_registry = new lobject.TValue(CT.LUA_TNIL, null);
this.panic = null;
this.atnativeerror = null;
this.version = null;
this.tmname = new Array(ltm.TMS.TM_N);
this.mt = new Array(LUA_NUMTAGS);
}
}
const luaE_extendCI = function(L) {
let ci = new CallInfo();
L.ci.next = ci;
ci.previous = L.ci;
ci.next = null;
L.ci = ci;
return ci;
};
const luaE_freeCI = function(L) {
let ci = L.ci;
ci.next = null;
};
const stack_init = function(L1, L) {
L1.stack = new Array(BASIC_STACK_SIZE);
L1.top = 0;
L1.stack_last = BASIC_STACK_SIZE - EXTRA_STACK;
/* initialize first ci */
let ci = L1.base_ci;
ci.next = ci.previous = null;
ci.callstatus = 0;
ci.funcOff = L1.top;
ci.func = L1.stack[L1.top];
L1.stack[L1.top++] = new lobject.TValue(CT.LUA_TNIL, null);
ci.top = L1.top + defs.LUA_MINSTACK;
L1.ci = ci;
};
const freestack = function(L) {
L.ci = L.base_ci;
luaE_freeCI(L);
L.stack = null;
};
/*
** Create registry table and its predefined values
*/
const init_registry = function(L, g) {
let registry = ltable.luaH_new(L);
g.l_registry.sethvalue(registry);
ltable.luaH_setint(registry, defs.LUA_RIDX_MAINTHREAD, new lobject.TValue(CT.LUA_TTHREAD, L));
ltable.luaH_setint(registry, defs.LUA_RIDX_GLOBALS, new lobject.TValue(CT.LUA_TTABLE, ltable.luaH_new(L)));
};
/*
** open parts of the state that may cause memory-allocation errors.
** ('g->version' !== NULL flags that the state was completely build)
*/
const f_luaopen = function(L) {
let g = L.l_G;
stack_init(L, L);
init_registry(L, g);
ltm.luaT_init(L);
g.version = lapi.lua_version(null);
};
const lua_newthread = function(L) {
let g = L.l_G;
let L1 = new lua_State(g);
L.stack[L.top] = new lobject.TValue(CT.LUA_TTHREAD, L1);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
L1.hookmask = L.hookmask;
L1.basehookcount = L.basehookcount;
L1.hook = L.hook;
L1.hookcount = L1.basehookcount;
stack_init(L1, L);
return L1;
};
const luaE_freethread = function(L, L1) {
lfunc.luaF_close(L1, L1.stack);
freestack(L1);
};
const lua_newstate = function() {
let g = new global_State();
let L = new lua_State(g);
g.mainthread = L;
if (ldo.luaD_rawrunprotected(L, f_luaopen, null) !== TS.LUA_OK) {
L = null;
}
return L;
};
const close_state = function(L) {
lfunc.luaF_close(L, L.stack); /* close all upvalues for this thread */
freestack(L);
};
const lua_close = function(L) {
L = L.l_G.mainthread; /* only the main thread can be closed */
close_state(L);
};
module.exports.lua_State = lua_State;
module.exports.CallInfo = CallInfo;
module.exports.CIST_OAH = (1<<0); /* original value of 'allowhook' */
module.exports.CIST_LUA = (1<<1); /* call is running a Lua function */
module.exports.CIST_HOOKED = (1<<2); /* call is running a debug hook */
module.exports.CIST_FRESH = (1<<3); /* call is running on a fresh invocation of luaV_execute */
module.exports.CIST_YPCALL = (1<<4); /* call is a yieldable protected call */
module.exports.CIST_TAIL = (1<<5); /* call was tail called */
module.exports.CIST_HOOKYIELD = (1<<6); /* last hook called yielded */
module.exports.CIST_LEQ = (1<<7); /* using __lt for __le */
module.exports.CIST_FIN = (1<<8); /* call is running a finalizer */
module.exports.EXTRA_STACK = EXTRA_STACK;
module.exports.lua_close = lua_close;
module.exports.lua_newstate = lua_newstate;
module.exports.lua_newthread = lua_newthread;
module.exports.luaE_extendCI = luaE_extendCI;
module.exports.luaE_freeCI = luaE_freeCI;
module.exports.luaE_freethread = luaE_freethread;
/***/ }),
/* 26 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const lobject = __webpack_require__(5);
const ldo = __webpack_require__(12);
const lstate = __webpack_require__(21);
const lstring = __webpack_require__(15);
const ltable = __webpack_require__(14);
const ldebug = __webpack_require__(19);
const lvm = __webpack_require__(27);
const CT = defs.constant_types;
const luaT_typenames_ = [
"no value",
"nil",
"boolean",
"userdata",
"number",
"string",
"table",
"function",
"userdata",
"thread",
"proto" /* this last case is used for tests only */
].map(e => defs.to_luastring(e));
const ttypename = function(t) {
return luaT_typenames_[t + 1];
};
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER TM" and "ORDER OP"
*/
const TMS = {
TM_INDEX: 0,
TM_NEWINDEX: 1,
TM_GC: 2,
TM_MODE: 3,
TM_LEN: 4,
TM_EQ: 5, /* last tag method with fast access */
TM_ADD: 6,
TM_SUB: 7,
TM_MUL: 8,
TM_MOD: 9,
TM_POW: 10,
TM_DIV: 11,
TM_IDIV: 12,
TM_BAND: 13 ,
TM_BOR: 14,
TM_BXOR: 15,
TM_SHL: 16,
TM_SHR: 17,
TM_UNM: 18,
TM_BNOT: 19,
TM_LT: 20,
TM_LE: 21,
TM_CONCAT: 22,
TM_CALL: 23,
TM_N: 24 /* number of elements in the enum */
};
const luaT_init = function(L) {
L.l_G.tmname[TMS.TM_INDEX] = new lstring.luaS_new(L, defs.to_luastring("__index", true));
L.l_G.tmname[TMS.TM_NEWINDEX] = new lstring.luaS_new(L, defs.to_luastring("__newindex", true));
L.l_G.tmname[TMS.TM_GC] = new lstring.luaS_new(L, defs.to_luastring("__gc", true));
L.l_G.tmname[TMS.TM_MODE] = new lstring.luaS_new(L, defs.to_luastring("__mode", true));
L.l_G.tmname[TMS.TM_LEN] = new lstring.luaS_new(L, defs.to_luastring("__len", true));
L.l_G.tmname[TMS.TM_EQ] = new lstring.luaS_new(L, defs.to_luastring("__eq", true));
L.l_G.tmname[TMS.TM_ADD] = new lstring.luaS_new(L, defs.to_luastring("__add", true));
L.l_G.tmname[TMS.TM_SUB] = new lstring.luaS_new(L, defs.to_luastring("__sub", true));
L.l_G.tmname[TMS.TM_MUL] = new lstring.luaS_new(L, defs.to_luastring("__mul", true));
L.l_G.tmname[TMS.TM_MOD] = new lstring.luaS_new(L, defs.to_luastring("__mod", true));
L.l_G.tmname[TMS.TM_POW] = new lstring.luaS_new(L, defs.to_luastring("__pow", true));
L.l_G.tmname[TMS.TM_DIV] = new lstring.luaS_new(L, defs.to_luastring("__div", true));
L.l_G.tmname[TMS.TM_IDIV] = new lstring.luaS_new(L, defs.to_luastring("__idiv", true));
L.l_G.tmname[TMS.TM_BAND] = new lstring.luaS_new(L, defs.to_luastring("__band", true));
L.l_G.tmname[TMS.TM_BOR] = new lstring.luaS_new(L, defs.to_luastring("__bor", true));
L.l_G.tmname[TMS.TM_BXOR] = new lstring.luaS_new(L, defs.to_luastring("__bxor", true));
L.l_G.tmname[TMS.TM_SHL] = new lstring.luaS_new(L, defs.to_luastring("__shl", true));
L.l_G.tmname[TMS.TM_SHR] = new lstring.luaS_new(L, defs.to_luastring("__shr", true));
L.l_G.tmname[TMS.TM_UNM] = new lstring.luaS_new(L, defs.to_luastring("__unm", true));
L.l_G.tmname[TMS.TM_BNOT] = new lstring.luaS_new(L, defs.to_luastring("__bnot", true));
L.l_G.tmname[TMS.TM_LT] = new lstring.luaS_new(L, defs.to_luastring("__lt", true));
L.l_G.tmname[TMS.TM_LE] = new lstring.luaS_new(L, defs.to_luastring("__le", true));
L.l_G.tmname[TMS.TM_CONCAT] = new lstring.luaS_new(L, defs.to_luastring("__concat", true));
L.l_G.tmname[TMS.TM_CALL] = new lstring.luaS_new(L, defs.to_luastring("__call", true));
};
/*
** Return the name of the type of an object. For tables and userdata
** with metatable, use their '__name' metafield, if present.
*/
const __name = defs.to_luastring('__name', true);
const luaT_objtypename = function(L, o) {
let mt;
if ((o.ttistable() && (mt = o.value.metatable) !== null) ||
(o.ttisfulluserdata() && (mt = o.value.metatable) !== null)) {
let name = ltable.luaH_getstr(mt, lstring.luaS_bless(L, __name));
if (name.ttisstring())
return name.svalue();
}
return ttypename(o.ttnov());
};
const luaT_callTM = function(L, f, p1, p2, p3, hasres) {
let func = L.top;
lobject.pushobj2s(L, f); /* push function (assume EXTRA_STACK) */
lobject.pushobj2s(L, p1); /* 1st argument */
lobject.pushobj2s(L, p2); /* 2nd argument */
if (!hasres) /* no result? 'p3' is third argument */
lobject.pushobj2s(L, p3); /* 3rd argument */
if (L.ci.callstatus & lstate.CIST_LUA)
ldo.luaD_call(L, func, hasres);
else
ldo.luaD_callnoyield(L, func, hasres);
if (hasres) { /* if has result, move it to its place */
let tv = L.stack[L.top-1];
delete L.stack[--L.top];
p3.setfrom(tv);
}
};
const luaT_callbinTM = function(L, p1, p2, res, event) {
let tm = luaT_gettmbyobj(L, p1, event);
if (tm.ttisnil())
tm = luaT_gettmbyobj(L, p2, event);
if (tm.ttisnil()) return false;
luaT_callTM(L, tm, p1, p2, res, 1);
return true;
};
const luaT_trybinTM = function(L, p1, p2, res, event) {
if (!luaT_callbinTM(L, p1, p2, res, event)) {
switch (event) {
case TMS.TM_CONCAT:
ldebug.luaG_concaterror(L, p1, p2);
case TMS.TM_BAND: case TMS.TM_BOR: case TMS.TM_BXOR:
case TMS.TM_SHL: case TMS.TM_SHR: case TMS.TM_BNOT: {
let n1 = lvm.tonumber(p1);
let n2 = lvm.tonumber(p2);
if (n1 !== false && n2 !== false)
ldebug.luaG_tointerror(L, p1, p2);
else
ldebug.luaG_opinterror(L, p1, p2, defs.to_luastring("perform bitwise operation on", true));
}
default:
ldebug.luaG_opinterror(L, p1, p2, defs.to_luastring("perform arithmetic on", true));
}
}
};
const luaT_callorderTM = function(L, p1, p2, event) {
let res = new lobject.TValue();
if (!luaT_callbinTM(L, p1, p2, res, event))
return null;
else
return !res.l_isfalse();
};
const fasttm = function(l, et, e) {
return et === null ? null :
(et.flags & (1 << e)) ? null : luaT_gettm(et, e, l.l_G.tmname[e]);
};
const luaT_gettm = function(events, event, ename) {
const tm = ltable.luaH_getstr(events, ename);
assert(event <= TMS.TM_EQ);
if (tm.ttisnil()) { /* no tag method? */
events.flags |= 1<<event; /* cache this fact */
return null;
}
else return tm;
};
const luaT_gettmbyobj = function(L, o, event) {
let mt;
switch(o.ttnov()) {
case CT.LUA_TTABLE:
case CT.LUA_TUSERDATA:
mt = o.value.metatable;
break;
default:
mt = L.l_G.mt[o.ttnov()];
}
return mt ? ltable.luaH_getstr(mt, L.l_G.tmname[event]) : lobject.luaO_nilobject;
};
module.exports.fasttm = fasttm;
module.exports.TMS = TMS;
module.exports.luaT_callTM = luaT_callTM;
module.exports.luaT_callbinTM = luaT_callbinTM;
module.exports.luaT_trybinTM = luaT_trybinTM;
module.exports.luaT_callorderTM = luaT_callorderTM;
module.exports.luaT_gettm = luaT_gettm;
module.exports.luaT_gettmbyobj = luaT_gettmbyobj;
module.exports.luaT_init = luaT_init;
module.exports.luaT_objtypename = luaT_objtypename;
module.exports.ttypename = ttypename;
/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const lopcodes = __webpack_require__(28);
const luaconf = __webpack_require__(18);
const lobject = __webpack_require__(5);
const lfunc = __webpack_require__(20);
const lstate = __webpack_require__(21);
const lstring = __webpack_require__(15);
const llimit = __webpack_require__(8);
const ldo = __webpack_require__(12);
const ltm = __webpack_require__(26);
const ltable = __webpack_require__(14);
const ldebug = __webpack_require__(19);
const CT = defs.constant_types;
const LUA_MULTRET = defs.LUA_MULTRET;
/*
** finish execution of an opcode interrupted by an yield
*/
const luaV_finishOp = function(L) {
let ci = L.ci;
let OCi = lopcodes.OpCodesI;
let base = ci.l_base;
let inst = ci.l_code[ci.l_savedpc - 1]; /* interrupted instruction */
let op = inst.opcode;
switch (op) { /* finish its execution */
case OCi.OP_ADD: case OCi.OP_SUB: case OCi.OP_MUL: case OCi.OP_DIV: case OCi.OP_IDIV:
case OCi.OP_BAND: case OCi.OP_BOR: case OCi.OP_BXOR: case OCi.OP_SHL: case OCi.OP_SHR:
case OCi.OP_MOD: case OCi.OP_POW:
case OCi.OP_UNM: case OCi.OP_BNOT: case OCi.OP_LEN:
case OCi.OP_GETTABUP: case OCi.OP_GETTABLE: case OCi.OP_SELF: {
lobject.setobjs2s(L, base + inst.A, L.top-1);
delete L.stack[--L.top];
break;
}
case OCi.OP_LE: case OCi.OP_LT: case OCi.OP_EQ: {
let res = !L.stack[L.top - 1].l_isfalse();
delete L.stack[--L.top];
if (ci.callstatus & lstate.CIST_LEQ) { /* "<=" using "<" instead? */
assert(op === OCi.OP_LE);
ci.callstatus ^= lstate.CIST_LEQ; /* clear mark */
res = !res; /* negate result */
}
assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_JMP);
if (res !== (inst.A ? true : false)) /* condition failed? */
ci.l_savedpc++; /* skip jump instruction */
break;
}
case OCi.OP_CONCAT: {
let top = L.top - 1; /* top when 'luaT_trybinTM' was called */
let b = inst.B; /* first element to concatenate */
let total = top - 1 - (base + b); /* yet to concatenate */
lobject.setobjs2s(L, top - 2, top); /* put TM result in proper position */
if (total > 1) { /* are there elements to concat? */
L.top = top - 1; /* top is one after last element (at top-2) */
luaV_concat(L, total); /* concat them (may yield again) */
}
/* move final result to final position */
lobject.setobjs2s(L, ci.l_base + inst.A, L.top - 1);
ldo.adjust_top(L, ci.top); /* restore top */
break;
}
case OCi.OP_TFORCALL: {
assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_TFORLOOP);
ldo.adjust_top(L, ci.top); /* correct top */
break;
}
case OCi.OP_CALL: {
if (inst.C - 1 >= 0) /* nresults >= 0? */
ldo.adjust_top(L, ci.top); /* adjust results */
break;
}
}
};
const RA = function(L, base, i) {
return base + i.A;
};
const RB = function(L, base, i) {
return base + i.B;
};
const RC = function(L, base, i) {
return base + i.C;
};
const RKB = function(L, base, k, i) {
return lopcodes.ISK(i.B) ? k[lopcodes.INDEXK(i.B)] : L.stack[base + i.B];
};
const RKC = function(L, base, k, i) {
return lopcodes.ISK(i.C) ? k[lopcodes.INDEXK(i.C)] : L.stack[base + i.C];
};
const luaV_execute = function(L) {
const OCi = lopcodes.OpCodesI;
let ci = L.ci;
ci.callstatus |= lstate.CIST_FRESH;
newframe:
for (;;) {
assert(ci === L.ci);
let cl = ci.func.value;
let k = cl.p.k;
let base = ci.l_base;
let i = ci.l_code[ci.l_savedpc++];
if (L.hookmask & (defs.LUA_MASKLINE | defs.LUA_MASKCOUNT)) {
ldebug.luaG_traceexec(L);
}
let ra = RA(L, base, i);
let opcode = i.opcode;
switch (opcode) {
case OCi.OP_MOVE: {
lobject.setobjs2s(L, ra, RB(L, base, i));
break;
}
case OCi.OP_LOADK: {
let konst = k[i.Bx];
lobject.setobj2s(L, ra, konst);
break;
}
case OCi.OP_LOADKX: {
assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_EXTRAARG);
let konst = k[ci.l_code[ci.l_savedpc++].Ax];
lobject.setobj2s(L, ra, konst);
break;
}
case OCi.OP_LOADBOOL: {
L.stack[ra].setbvalue(i.B !== 0);
if (i.C !== 0)
ci.l_savedpc++; /* skip next instruction (if C) */
break;
}
case OCi.OP_LOADNIL: {
for (let j = 0; j <= i.B; j++)
L.stack[ra + j].setnilvalue();
break;
}
case OCi.OP_GETUPVAL: {
let b = i.B;
lobject.setobj2s(L, ra, cl.upvals[b].v);
break;
}
case OCi.OP_GETTABUP: {
let upval = cl.upvals[i.B].v;
let rc = RKC(L, base, k, i);
luaV_gettable(L, upval, rc, ra);
break;
}
case OCi.OP_GETTABLE: {
let rb = L.stack[RB(L, base, i)];
let rc = RKC(L, base, k, i);
luaV_gettable(L, rb, rc, ra);
break;
}
case OCi.OP_SETTABUP: {
let upval = cl.upvals[i.A].v;
let rb = RKB(L, base, k, i);
let rc = RKC(L, base, k, i);
settable(L, upval, rb, rc);
break;
}
case OCi.OP_SETUPVAL: {
let uv = cl.upvals[i.B];
uv.v.setfrom(L.stack[ra]);
break;
}
case OCi.OP_SETTABLE: {
let table = L.stack[ra];
let key = RKB(L, base, k, i);
let v = RKC(L, base, k, i);
settable(L, table, key, v);
break;
}
case OCi.OP_NEWTABLE: {
L.stack[ra].sethvalue(ltable.luaH_new(L));
break;
}
case OCi.OP_SELF: {
let rb = RB(L, base, i);
let rc = RKC(L, base, k, i);
lobject.setobjs2s(L, ra + 1, rb);
luaV_gettable(L, L.stack[rb], rc, ra);
break;
}
case OCi.OP_ADD: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if (op1.ttisinteger() && op2.ttisinteger()) {
L.stack[ra].setivalue((op1.value + op2.value)|0);
} else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(numberop1 + numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_ADD);
}
break;
}
case OCi.OP_SUB: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if (op1.ttisinteger() && op2.ttisinteger()) {
L.stack[ra].setivalue((op1.value - op2.value)|0);
} else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(numberop1 - numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_SUB);
}
break;
}
case OCi.OP_MUL: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if (op1.ttisinteger() && op2.ttisinteger()) {
L.stack[ra].setivalue(Math.imul(op1.value, op2.value));
} else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(numberop1 * numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_MUL);
}
break;
}
case OCi.OP_MOD: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if (op1.ttisinteger() && op2.ttisinteger()) {
L.stack[ra].setivalue(luaV_mod(L, op1.value, op2.value));
} else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(llimit.luai_nummod(L, numberop1, numberop2));
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_MOD);
}
break;
}
case OCi.OP_POW: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(Math.pow(numberop1, numberop2));
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_POW);
}
break;
}
case OCi.OP_DIV: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(numberop1 / numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_DIV);
}
break;
}
case OCi.OP_IDIV: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if (op1.ttisinteger() && op2.ttisinteger()) {
L.stack[ra].setivalue(luaV_div(L, op1.value, op2.value));
} else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(Math.floor(numberop1 / numberop2));
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_IDIV);
}
break;
}
case OCi.OP_BAND: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tointeger(op1)) !== false && (numberop2 = tointeger(op2)) !== false) {
L.stack[ra].setivalue(numberop1 & numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_BAND);
}
break;
}
case OCi.OP_BOR: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tointeger(op1)) !== false && (numberop2 = tointeger(op2)) !== false) {
L.stack[ra].setivalue(numberop1 | numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_BOR);
}
break;
}
case OCi.OP_BXOR: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tointeger(op1)) !== false && (numberop2 = tointeger(op2)) !== false) {
L.stack[ra].setivalue(numberop1 ^ numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_BXOR);
}
break;
}
case OCi.OP_SHL: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tointeger(op1)) !== false && (numberop2 = tointeger(op2)) !== false) {
L.stack[ra].setivalue(luaV_shiftl(numberop1, numberop2));
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_SHL);
}
break;
}
case OCi.OP_SHR: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tointeger(op1)) !== false && (numberop2 = tointeger(op2)) !== false) {
L.stack[ra].setivalue(luaV_shiftl(numberop1, -numberop2));
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_SHR);
}
break;
}
case OCi.OP_UNM: {
let op = L.stack[RB(L, base, i)];
let numberop;
if (op.ttisinteger()) {
L.stack[ra].setivalue((-op.value)|0);
} else if ((numberop = tonumber(op)) !== false) {
L.stack[ra].setfltvalue(-numberop);
} else {
ltm.luaT_trybinTM(L, op, op, L.stack[ra], ltm.TMS.TM_UNM);
}
break;
}
case OCi.OP_BNOT: {
let op = L.stack[RB(L, base, i)];
if (op.ttisinteger()) {
L.stack[ra].setivalue(~op.value);
} else {
ltm.luaT_trybinTM(L, op, op, L.stack[ra], ltm.TMS.TM_BNOT);
}
break;
}
case OCi.OP_NOT: {
let op = L.stack[RB(L, base, i)];
L.stack[ra].setbvalue(op.l_isfalse());
break;
}
case OCi.OP_LEN: {
luaV_objlen(L, L.stack[ra], L.stack[RB(L, base, i)]);
break;
}
case OCi.OP_CONCAT: {
let b = i.B;
let c = i.C;
L.top = base + c + 1; /* mark the end of concat operands */
luaV_concat(L, c - b + 1);
let rb = base + b;
lobject.setobjs2s(L, ra, rb);
ldo.adjust_top(L, ci.top); /* restore top */
break;
}
case OCi.OP_JMP: {
dojump(L, ci, i, 0);
break;
}
case OCi.OP_EQ: {
if (luaV_equalobj(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A)
ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_LT: {
if (luaV_lessthan(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A)
ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_LE: {
if (luaV_lessequal(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A)
ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_TEST: {
if (i.C ? L.stack[ra].l_isfalse() : !L.stack[ra].l_isfalse())
ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_TESTSET: {
let rbIdx = RB(L, base, i);
let rb = L.stack[rbIdx];
if (i.C ? rb.l_isfalse() : !rb.l_isfalse())
ci.l_savedpc++;
else {
lobject.setobjs2s(L, ra, rbIdx);
donextjump(L, ci);
}
break;
}
case OCi.OP_CALL: {
let b = i.B;
let nresults = i.C - 1;
if (b !== 0) ldo.adjust_top(L, ra+b); /* else previous instruction set top */
if (ldo.luaD_precall(L, ra, nresults)) {
if (nresults >= 0)
ldo.adjust_top(L, ci.top); /* adjust results */
} else {
ci = L.ci;
continue newframe;
}
break;
}
case OCi.OP_TAILCALL: {
let b = i.B;
if (b !== 0) ldo.adjust_top(L, ra+b); /* else previous instruction set top */
if (ldo.luaD_precall(L, ra, LUA_MULTRET)) { // JS function
} else {
/* tail call: put called frame (n) in place of caller one (o) */
let nci = L.ci;
let oci = nci.previous;
let nfunc = nci.func;
let nfuncOff = nci.funcOff;
let ofuncOff = oci.funcOff;
let lim = nci.l_base + nfunc.value.p.numparams;
if (cl.p.p.length > 0) lfunc.luaF_close(L, oci.l_base);
for (let aux = 0; nfuncOff + aux < lim; aux++)
lobject.setobjs2s(L, ofuncOff + aux, nfuncOff + aux);
oci.l_base = ofuncOff + (nci.l_base - nfuncOff);
oci.top = ofuncOff + (L.top - nfuncOff);
ldo.adjust_top(L, oci.top); /* correct top */
oci.l_code = nci.l_code;
oci.l_savedpc = nci.l_savedpc;
oci.callstatus |= lstate.CIST_TAIL;
oci.next = null;
ci = L.ci = oci;
assert(L.top === oci.l_base + L.stack[ofuncOff].value.p.maxstacksize);
continue newframe;
}
break;
}
case OCi.OP_RETURN: {
if (cl.p.p.length > 0) lfunc.luaF_close(L, base);
let b = ldo.luaD_poscall(L, ci, ra, (i.B !== 0 ? i.B - 1 : L.top - ra));
if (ci.callstatus & lstate.CIST_FRESH)
return; /* external invocation: return */
/* invocation via reentry: continue execution */
ci = L.ci;
if (b) ldo.adjust_top(L, ci.top);
assert(ci.callstatus & lstate.CIST_LUA);
assert(ci.l_code[ci.l_savedpc - 1].opcode === OCi.OP_CALL);
continue newframe;
}
case OCi.OP_FORLOOP: {
if (L.stack[ra].ttisinteger()) { /* integer loop? */
let step = L.stack[ra + 2].value;
let idx = (L.stack[ra].value + step)|0;
let limit = L.stack[ra + 1].value;
if (0 < step ? idx <= limit : limit <= idx) {
ci.l_savedpc += i.sBx;
L.stack[ra].chgivalue(idx); /* update internal index... */
L.stack[ra + 3].setivalue(idx);
}
} else { /* floating loop */
let step = L.stack[ra + 2].value;
let idx = L.stack[ra].value + step;
let limit = L.stack[ra + 1].value;
if (0 < step ? idx <= limit : limit <= idx) {
ci.l_savedpc += i.sBx;
L.stack[ra].chgfltvalue(idx); /* update internal index... */
L.stack[ra + 3].setfltvalue(idx);
}
}
break;
}
case OCi.OP_FORPREP: {
let init = L.stack[ra];
let plimit = L.stack[ra + 1];
let pstep = L.stack[ra + 2];
let forlim;
if (init.ttisinteger() && pstep.ttisinteger() && (forlim = forlimit(plimit, pstep.value))) {
/* all values are integer */
let initv = forlim.stopnow ? 0 : init.value;
plimit.value = forlim.ilimit;
init.value = (initv - pstep.value)|0;
} else { /* try making all values floats */
let nlimit, nstep, ninit;
if ((nlimit = tonumber(plimit)) === false)
ldebug.luaG_runerror(L, defs.to_luastring("'for' limit must be a number", true));
L.stack[ra + 1].setfltvalue(nlimit);
if ((nstep = tonumber(pstep)) === false)
ldebug.luaG_runerror(L, defs.to_luastring("'for' step must be a number", true));
L.stack[ra + 2].setfltvalue(nstep);
if ((ninit = tonumber(init)) === false)
ldebug.luaG_runerror(L, defs.to_luastring("'for' initial value must be a number", true));
L.stack[ra].setfltvalue(ninit - nstep);
}
ci.l_savedpc += i.sBx;
break;
}
case OCi.OP_TFORCALL: {
let cb = ra + 3; /* call base */
lobject.setobjs2s(L, cb+2, ra+2);
lobject.setobjs2s(L, cb+1, ra+1);
lobject.setobjs2s(L, cb, ra);
ldo.adjust_top(L, cb+3); /* func. + 2 args (state and index) */
ldo.luaD_call(L, cb, i.C);
ldo.adjust_top(L, ci.top);
/* go straight to OP_TFORLOOP */
i = ci.l_code[ci.l_savedpc++];
ra = RA(L, base, i);
assert(i.opcode === OCi.OP_TFORLOOP);
}
/* fall through */
case OCi.OP_TFORLOOP: {
if (!L.stack[ra + 1].ttisnil()) { /* continue loop? */
lobject.setobjs2s(L, ra, ra + 1); /* save control variable */
ci.l_savedpc += i.sBx; /* jump back */
}
break;
}
case OCi.OP_SETLIST: {
let n = i.B;
let c = i.C;
if (n === 0) n = L.top - ra - 1;
if (c === 0) {
assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_EXTRAARG);
c = ci.l_code[ci.l_savedpc++].Ax;
}
let h = L.stack[ra].value;
let last = ((c - 1) * lopcodes.LFIELDS_PER_FLUSH) + n;
for (; n > 0; n--) {
ltable.luaH_setint(h, last--, L.stack[ra + n]);
}
ldo.adjust_top(L, ci.top); /* correct top (in case of previous open call) */
break;
}
case OCi.OP_CLOSURE: {
let p = cl.p.p[i.Bx];
let ncl = getcached(p, cl.upvals, L.stack, base); /* cached closure */
if (ncl === null) /* no match? */
pushclosure(L, p, cl.upvals, base, ra); /* create a new one */
else
L.stack[ra].setclLvalue(ncl);
break;
}
case OCi.OP_VARARG: {
let b = i.B - 1;
let n = base - ci.funcOff - cl.p.numparams - 1;
let j;
if (n < 0) /* less arguments than parameters? */
n = 0; /* no vararg arguments */
if (b < 0) {
b = n; /* get all var. arguments */
ldo.luaD_checkstack(L, n);
ldo.adjust_top(L, ra + n);
}
for (j = 0; j < b && j < n; j++)
lobject.setobjs2s(L, ra + j, base - n + j);
for (; j < b; j++) /* complete required results with nil */
L.stack[ra + j].setnilvalue();
break;
}
case OCi.OP_EXTRAARG: {
throw Error("invalid opcode");
}
}
}
};
const dojump = function(L, ci, i, e) {
let a = i.A;
if (a !== 0) lfunc.luaF_close(L, ci.l_base + a - 1);
ci.l_savedpc += i.sBx + e;
};
const donextjump = function(L, ci) {
dojump(L, ci, ci.l_code[ci.l_savedpc], 1);
};
const luaV_lessthan = function(L, l, r) {
if (l.ttisnumber() && r.ttisnumber())
return LTnum(l, r) ? 1 : 0;
else if (l.ttisstring() && r.ttisstring())
return l_strcmp(l.tsvalue(), r.tsvalue()) < 0 ? 1 : 0;
else {
let res = ltm.luaT_callorderTM(L, l, r, ltm.TMS.TM_LT);
if (res === null)
ldebug.luaG_ordererror(L, l, r);
return res ? 1 : 0;
}
};
const luaV_lessequal = function(L, l, r) {
let res;
if (l.ttisnumber() && r.ttisnumber())
return LEnum(l, r) ? 1 : 0;
else if (l.ttisstring() && r.ttisstring())
return l_strcmp(l.tsvalue(), r.tsvalue()) <= 0 ? 1 : 0;
else {
res = ltm.luaT_callorderTM(L, l, r, ltm.TMS.TM_LE);
if (res !== null)
return res ? 1 : 0;
}
/* try 'lt': */
L.ci.callstatus |= lstate.CIST_LEQ; /* mark it is doing 'lt' for 'le' */
res = ltm.luaT_callorderTM(L, r, l, ltm.TMS.TM_LT);
L.ci.callstatus ^= lstate.CIST_LEQ; /* clear mark */
if (res === null)
ldebug.luaG_ordererror(L, l, r);
return res ? 0 : 1; /* result is negated */
};
const luaV_equalobj = function(L, t1, t2) {
if (t1.ttype() !== t2.ttype()) { /* not the same variant? */
if (t1.ttnov() !== t2.ttnov() || t1.ttnov() !== CT.LUA_TNUMBER)
return 0; /* only numbers can be equal with different variants */
else { /* two numbers with different variants */
/* OPTIMIZATION: instead of calling luaV_tointeger we can just let JS do the comparison */
return (t1.value === t2.value) ? 1 : 0;
}
}
let tm;
/* values have same type and same variant */
switch(t1.ttype()) {
case CT.LUA_TNIL:
return 1;
case CT.LUA_TBOOLEAN:
return t1.value == t2.value ? 1 : 0; // Might be 1 or true
case CT.LUA_TLIGHTUSERDATA:
case CT.LUA_TNUMINT:
case CT.LUA_TNUMFLT:
case CT.LUA_TLCF:
return t1.value === t2.value ? 1 : 0;
case CT.LUA_TSHRSTR:
case CT.LUA_TLNGSTR: {
return lstring.luaS_eqlngstr(t1.tsvalue(), t2.tsvalue()) ? 1 : 0;
}
case CT.LUA_TUSERDATA:
case CT.LUA_TTABLE:
if (t1.value === t2.value) return 1;
else if (L === null) return 0;
tm = ltm.fasttm(L, t1.value.metatable, ltm.TMS.TM_EQ);
if (tm === null)
tm = ltm.fasttm(L, t2.value.metatable, ltm.TMS.TM_EQ);
break;
default:
return t1.value === t2.value ? 1 : 0;
}
if (tm === null) /* no TM? */
return 0;
let tv = new lobject.TValue(); /* doesn't use the stack */
ltm.luaT_callTM(L, tm, t1, t2, tv, 1);
return tv.l_isfalse() ? 0 : 1;
};
const luaV_rawequalobj = function(t1, t2) {
return luaV_equalobj(null, t1, t2);
};
const forlimit = function(obj, step) {
let stopnow = false;
let ilimit = luaV_tointeger(obj, step < 0 ? 2 : 1);
if (ilimit === false) {
let n = tonumber(obj);
if (n === false)
return false;
if (0 < n) {
ilimit = llimit.LUA_MAXINTEGER;
if (step < 0) stopnow = true;
} else {
ilimit = llimit.LUA_MININTEGER;
if (step >= 0) stopnow = true;
}
}
return {
stopnow: stopnow,
ilimit: ilimit
};
};
/*
** try to convert a value to an integer, rounding according to 'mode':
** mode === 0: accepts only integral values
** mode === 1: takes the floor of the number
** mode === 2: takes the ceil of the number
*/
const luaV_tointeger = function(obj, mode) {
if (obj.ttisfloat()) {
let n = obj.value;
let f = Math.floor(n);
if (n !== f) { /* not an integral value? */
if (mode === 0)
return false; /* fails if mode demands integral value */
else if (mode > 1) /* needs ceil? */
f += 1; /* convert floor to ceil (remember: n !== f) */
}
return luaconf.lua_numbertointeger(f);
} else if (obj.ttisinteger()) {
return obj.value;
} else if (cvt2num(obj)) {
let v = lobject.luaO_str2num(obj.svalue());
if (v !== false)
return luaV_tointeger(v, mode);
}
return false;
};
const tointeger = function(o) {
return o.ttisinteger() ? o.value : luaV_tointeger(o, 0);
};
const tonumber = function(o) {
if (o.ttnov() === CT.LUA_TNUMBER)
return o.value;
if (cvt2num(o)) { /* string convertible to number? */
let v = lobject.luaO_str2num(o.svalue());
if (v !== false)
return v.value;
}
return false;
};
/*
** Return 'l < r', for numbers.
** As fengari uses javascript numbers for both floats and integers and has
** correct semantics, we can just compare values.
*/
const LTnum = function(l, r) {
return l.value < r.value;
};
/*
** Return 'l <= r', for numbers.
*/
const LEnum = function(l, r) {
return l.value <= r.value;
};
/*
** Compare two strings 'ls' x 'rs', returning an integer smaller-equal-
** -larger than zero if 'ls' is smaller-equal-larger than 'rs'.
*/
const l_strcmp = function(ls, rs) {
let l = lstring.luaS_hashlongstr(ls);
let r = lstring.luaS_hashlongstr(rs);
/* In fengari we assume string hash has same collation as byte values */
if (l === r)
return 0;
else if (l < r)
return -1;
else
return 1;
};
/*
** Main operation 'ra' = #rb'.
*/
const luaV_objlen = function(L, ra, rb) {
let tm;
switch(rb.ttype()) {
case CT.LUA_TTABLE: {
let h = rb.value;
tm = ltm.fasttm(L, h.metatable, ltm.TMS.TM_LEN);
if (tm !== null) break; /* metamethod? break switch to call it */
ra.setivalue(ltable.luaH_getn(h)); /* else primitive len */
return;
}
case CT.LUA_TSHRSTR:
case CT.LUA_TLNGSTR:
ra.setivalue(rb.vslen());
return;
default: {
tm = ltm.luaT_gettmbyobj(L, rb, ltm.TMS.TM_LEN);
if (tm.ttisnil())
ldebug.luaG_typeerror(L, rb, defs.to_luastring("get length of", true));
break;
}
}
ltm.luaT_callTM(L, tm, rb, rb, ra, 1);
};
const luaV_div = function(L, m, n) {
if (n === 0)
ldebug.luaG_runerror(L, defs.to_luastring("attempt to divide by zero"));
return Math.floor(m / n)|0;
};
// % semantic on negative numbers is different in js
const luaV_mod = function(L, m, n) {
if (n === 0)
ldebug.luaG_runerror(L, defs.to_luastring("attempt to perform 'n%%0'"));
return (m - Math.floor(m / n) * n)|0;
};
const NBITS = 32;
const luaV_shiftl = function(x, y) {
if (y < 0) { /* shift right? */
if (y <= -NBITS) return 0;
else return x >>> -y;
}
else { /* shift left */
if (y >= NBITS) return 0;
else return x << y;
}
};
/*
** check whether cached closure in prototype 'p' may be reused, that is,
** whether there is a cached closure with the same upvalues needed by
** new closure to be created.
*/
const getcached = function(p, encup, stack, base) {
let c = p.cache;
if (c !== null) { /* is there a cached closure? */
let uv = p.upvalues;
let nup = uv.length;
for (let i = 0; i < nup; i++) { /* check whether it has right upvalues */
let v = uv[i].instack ? stack[base + uv[i].idx] : encup[uv[i].idx].v;
if (c.upvals[i].v !== v)
return null; /* wrong upvalue; cannot reuse closure */
}
}
return c; /* return cached closure (or NULL if no cached closure) */
};
/*
** create a new Lua closure, push it in the stack, and initialize
** its upvalues.
*/
const pushclosure = function(L, p, encup, base, ra) {
let nup = p.upvalues.length;
let uv = p.upvalues;
let ncl = new lobject.LClosure(L, nup);
ncl.p = p;
L.stack[ra].setclLvalue(ncl);
for (let i = 0; i < nup; i++) {
if (uv[i].instack)
ncl.upvals[i] = lfunc.luaF_findupval(L, base + uv[i].idx);
else
ncl.upvals[i] = encup[uv[i].idx];
ncl.upvals[i].refcount++;
}
p.cache = ncl; /* save it on cache for reuse */
};
const cvt2str = function(o) {
return o.ttisnumber();
};
const cvt2num = function(o) {
return o.ttisstring();
};
const tostring = function(L, i) {
let o = L.stack[i];
if (o.ttisstring()) return true;
if (cvt2str(o)) {
lobject.luaO_tostring(L, o);
return true;
}
return false;
};
const isemptystr = function(o) {
return o.ttisstring() && o.vslen() === 0;
};
/*
** Main operation for concatenation: concat 'total' values in the stack,
** from 'L->top - total' up to 'L->top - 1'.
*/
const luaV_concat = function(L, total) {
assert(total >= 2);
do {
let top = L.top;
let n = 2; /* number of elements handled in this pass (at least 2) */
if (!(L.stack[top-2].ttisstring() || cvt2str(L.stack[top-2])) || !tostring(L, top - 1)) {
ltm.luaT_trybinTM(L, L.stack[top-2], L.stack[top-1], L.stack[top-2], ltm.TMS.TM_CONCAT);
} else if (isemptystr(L.stack[top-1])) {
tostring(L, top - 2);
} else if (isemptystr(L.stack[top-2])) {
lobject.setobjs2s(L, top - 2, top - 1);
} else {
/* at least two non-empty string values; get as many as possible */
let toconcat = new Array(total);
toconcat[total-1] = L.stack[top-1].svalue();
for (n = 1; n < total; n++) {
if (!tostring(L, top - n - 1)) {
toconcat = toconcat.slice(total-n);
break;
}
toconcat[total-n-1] = L.stack[top - n - 1].svalue();
}
let ts = lstring.luaS_bless(L, Array.prototype.concat.apply([], toconcat));
lobject.setsvalue2s(L, top - n, ts);
}
total -= n - 1; /* got 'n' strings to create 1 new */
/* popped 'n' strings and pushed one */
for (; L.top > top-(n-1);)
delete L.stack[--L.top];
} while (total > 1); /* repeat until only 1 result left */
};
const MAXTAGLOOP = 2000;
const luaV_gettable = function(L, t, key, ra) {
for (let loop = 0; loop < MAXTAGLOOP; loop++) {
let tm;
if (!t.ttistable()) {
tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_INDEX);
if (tm.ttisnil())
ldebug.luaG_typeerror(L, t, defs.to_luastring('index', true)); /* no metamethod */
/* else will try the metamethod */
} else {
let slot = ltable.luaH_get(L, t.value, key);
if (!slot.ttisnil()) {
lobject.setobj2s(L, ra, slot);
return;
} else { /* 't' is a table */
tm = ltm.fasttm(L, t.value.metatable, ltm.TMS.TM_INDEX); /* table's metamethod */
if (tm === null) { /* no metamethod? */
L.stack[ra].setnilvalue(); /* result is nil */
return;
}
}
/* else will try the metamethod */
}
if (tm.ttisfunction()) { /* is metamethod a function? */
ltm.luaT_callTM(L, tm, t, key, L.stack[ra], 1); /* call it */
return;
}
t = tm; /* else try to access 'tm[key]' */
}
ldebug.luaG_runerror(L, defs.to_luastring("'__index' chain too long; possible loop", true));
};
const settable = function(L, t, key, val) {
for (let loop = 0; loop < MAXTAGLOOP; loop++) {
let tm;
if (t.ttistable()) {
let h = t.value; /* save 't' table */
let slot = ltable.luaH_set(L, h, key);
if (!slot.ttisnil() || (tm = ltm.fasttm(L, h.metatable, ltm.TMS.TM_NEWINDEX)) === null) {
if (val.ttisnil())
ltable.luaH_delete(L, h, key);
else
slot.setfrom(val);
ltable.invalidateTMcache(h);
return;
}
/* else will try the metamethod */
} else { /* not a table; check metamethod */
if ((tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_NEWINDEX)).ttisnil())
ldebug.luaG_typeerror(L, t, defs.to_luastring('index', true));
}
/* try the metamethod */
if (tm.ttisfunction()) {
ltm.luaT_callTM(L, tm, t, key, val, 0);
return;
}
t = tm; /* else repeat assignment over 'tm' */
}
ldebug.luaG_runerror(L, defs.to_luastring("'__newindex' chain too long; possible loop", true));
};
module.exports.cvt2str = cvt2str;
module.exports.cvt2num = cvt2num;
module.exports.luaV_gettable = luaV_gettable;
module.exports.luaV_concat = luaV_concat;
module.exports.luaV_div = luaV_div;
module.exports.luaV_equalobj = luaV_equalobj;
module.exports.luaV_execute = luaV_execute;
module.exports.luaV_finishOp = luaV_finishOp;
module.exports.luaV_lessequal = luaV_lessequal;
module.exports.luaV_lessthan = luaV_lessthan;
module.exports.luaV_mod = luaV_mod;
module.exports.luaV_objlen = luaV_objlen;
module.exports.luaV_rawequalobj = luaV_rawequalobj;
module.exports.luaV_shiftl = luaV_shiftl;
module.exports.luaV_tointeger = luaV_tointeger;
module.exports.settable = settable;
module.exports.tointeger = tointeger;
module.exports.tonumber = tonumber;
/***/ }),
/* 28 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const OpCodes = [
"MOVE",
"LOADK",
"LOADKX",
"LOADBOOL",
"LOADNIL",
"GETUPVAL",
"GETTABUP",
"GETTABLE",
"SETTABUP",
"SETUPVAL",
"SETTABLE",
"NEWTABLE",
"SELF",
"ADD",
"SUB",
"MUL",
"MOD",
"POW",
"DIV",
"IDIV",
"BAND",
"BOR",
"BXOR",
"SHL",
"SHR",
"UNM",
"BNOT",
"NOT",
"LEN",
"CONCAT",
"JMP",
"EQ",
"LT",
"LE",
"TEST",
"TESTSET",
"CALL",
"TAILCALL",
"RETURN",
"FORLOOP",
"FORPREP",
"TFORCALL",
"TFORLOOP",
"SETLIST",
"CLOSURE",
"VARARG",
"EXTRAARG"
];
const OpCodesI = {
OP_MOVE: 0,
OP_LOADK: 1,
OP_LOADKX: 2,
OP_LOADBOOL: 3,
OP_LOADNIL: 4,
OP_GETUPVAL: 5,
OP_GETTABUP: 6,
OP_GETTABLE: 7,
OP_SETTABUP: 8,
OP_SETUPVAL: 9,
OP_SETTABLE: 10,
OP_NEWTABLE: 11,
OP_SELF: 12,
OP_ADD: 13,
OP_SUB: 14,
OP_MUL: 15,
OP_MOD: 16,
OP_POW: 17,
OP_DIV: 18,
OP_IDIV: 19,
OP_BAND: 20,
OP_BOR: 21,
OP_BXOR: 22,
OP_SHL: 23,
OP_SHR: 24,
OP_UNM: 25,
OP_BNOT: 26,
OP_NOT: 27,
OP_LEN: 28,
OP_CONCAT: 29,
OP_JMP: 30,
OP_EQ: 31,
OP_LT: 32,
OP_LE: 33,
OP_TEST: 34,
OP_TESTSET: 35,
OP_CALL: 36,
OP_TAILCALL: 37,
OP_RETURN: 38,
OP_FORLOOP: 39,
OP_FORPREP: 40,
OP_TFORCALL: 41,
OP_TFORLOOP: 42,
OP_SETLIST: 43,
OP_CLOSURE: 44,
OP_VARARG: 45,
OP_EXTRAARG: 46
};
/*
** masks for instruction properties. The format is:
** bits 0-1: op mode
** bits 2-3: C arg mode
** bits 4-5: B arg mode
** bit 6: instruction set register A
** bit 7: operator is a test (next instruction must be a jump)
*/
const OpArgN = 0; /* argument is not used */
const OpArgU = 1; /* argument is used */
const OpArgR = 2; /* argument is a register or a jump offset */
const OpArgK = 3; /* argument is a constant or register/constant */
/* basic instruction format */
const iABC = 0;
const iABx = 1;
const iAsBx = 2;
const iAx = 3;
const luaP_opmodes = [
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iABC, /* OP_MOVE */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgN << 2 | iABx, /* OP_LOADK */
0 << 7 | 1 << 6 | OpArgN << 4 | OpArgN << 2 | iABx, /* OP_LOADKX */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgU << 2 | iABC, /* OP_LOADBOOL */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgN << 2 | iABC, /* OP_LOADNIL */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgN << 2 | iABC, /* OP_GETUPVAL */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgK << 2 | iABC, /* OP_GETTABUP */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgK << 2 | iABC, /* OP_GETTABLE */
0 << 7 | 0 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_SETTABUP */
0 << 7 | 0 << 6 | OpArgU << 4 | OpArgN << 2 | iABC, /* OP_SETUPVAL */
0 << 7 | 0 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_SETTABLE */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgU << 2 | iABC, /* OP_NEWTABLE */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgK << 2 | iABC, /* OP_SELF */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_ADD */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_SUB */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_MUL */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_MOD */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_POW */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_DIV */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_IDIV */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_BAND */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_BOR */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_BXOR */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_SHL */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_SHR */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iABC, /* OP_UNM */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iABC, /* OP_BNOT */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iABC, /* OP_NOT */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iABC, /* OP_LEN */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgR << 2 | iABC, /* OP_CONCAT */
0 << 7 | 0 << 6 | OpArgR << 4 | OpArgN << 2 | iAsBx, /* OP_JMP */
1 << 7 | 0 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_EQ */
1 << 7 | 0 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_LT */
1 << 7 | 0 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_LE */
1 << 7 | 0 << 6 | OpArgN << 4 | OpArgU << 2 | iABC, /* OP_TEST */
1 << 7 | 1 << 6 | OpArgR << 4 | OpArgU << 2 | iABC, /* OP_TESTSET */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgU << 2 | iABC, /* OP_CALL */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgU << 2 | iABC, /* OP_TAILCALL */
0 << 7 | 0 << 6 | OpArgU << 4 | OpArgN << 2 | iABC, /* OP_RETURN */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iAsBx, /* OP_FORLOOP */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iAsBx, /* OP_FORPREP */
0 << 7 | 0 << 6 | OpArgN << 4 | OpArgU << 2 | iABC, /* OP_TFORCALL */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iAsBx, /* OP_TFORLOOP */
0 << 7 | 0 << 6 | OpArgU << 4 | OpArgU << 2 | iABC, /* OP_SETLIST */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgN << 2 | iABx, /* OP_CLOSURE */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgN << 2 | iABC, /* OP_VARARG */
0 << 7 | 0 << 6 | OpArgU << 4 | OpArgU << 2 | iAx /* OP_EXTRAARG */
];
const getOpMode = function(m) {
return luaP_opmodes[m] & 3;
};
const getBMode = function(m) {
return (luaP_opmodes[m] >> 4) & 3;
};
const getCMode = function(m) {
return (luaP_opmodes[m] >> 2) & 3;
};
const testAMode = function(m) {
return luaP_opmodes[m] & (1 << 6);
};
const testTMode = function(m) {
return luaP_opmodes[m] & (1 << 7);
};
const SIZE_C = 9;
const SIZE_B = 9;
const SIZE_Bx = (SIZE_C + SIZE_B);
const SIZE_A = 8;
const SIZE_Ax = (SIZE_C + SIZE_B + SIZE_A);
const SIZE_OP = 6;
const POS_OP = 0;
const POS_A = (POS_OP + SIZE_OP);
const POS_C = (POS_A + SIZE_A);
const POS_B = (POS_C + SIZE_C);
const POS_Bx = POS_C;
const POS_Ax = POS_A;
const MAXARG_Bx = ((1 << SIZE_Bx) - 1);
const MAXARG_sBx = (MAXARG_Bx >> 1); /* 'sBx' is signed */
const MAXARG_Ax = ((1<<SIZE_Ax)-1);
const MAXARG_A = ((1 << SIZE_A) - 1);
const MAXARG_B = ((1 << SIZE_B) - 1);
const MAXARG_C = ((1 << SIZE_C) - 1);
/* this bit 1 means constant (0 means register) */
const BITRK = (1 << (SIZE_B - 1));
const MAXINDEXRK = (BITRK - 1);
/*
** invalid register that fits in 8 bits
*/
const NO_REG = MAXARG_A;
/* test whether value is a constant */
const ISK = function (x) {
return x & BITRK;
};
/* gets the index of the constant */
const INDEXK = function (r) {
return r & ~BITRK;
};
/* code a constant index as a RK value */
const RKASK = function(x) {
return x | BITRK;
};
/* creates a mask with 'n' 1 bits at position 'p' */
const MASK1 = function(n, p) {
return ((~((~0)<<(n)))<<(p));
};
/* creates a mask with 'n' 0 bits at position 'p' */
const MASK0 = function(n, p) {
return (~MASK1(n, p));
};
const GET_OPCODE = function(i) {
return i.opcode;
};
const SET_OPCODE = function(i, o) {
i.code = (i.code & MASK0(SIZE_OP, POS_OP)) | ((o << POS_OP) & MASK1(SIZE_OP, POS_OP));
return fullins(i);
};
const setarg = function(i, v, pos, size) {
i.code = (i.code & MASK0(size, pos)) | ((v << pos) & MASK1(size, pos));
return fullins(i);
};
const GETARG_A = function(i) {
return i.A;
};
const SETARG_A = function(i,v) {
return setarg(i, v, POS_A, SIZE_A);
};
const GETARG_B = function(i) {
return i.B;
};
const SETARG_B = function(i,v) {
return setarg(i, v, POS_B, SIZE_B);
};
const GETARG_C = function(i) {
return i.C;
};
const SETARG_C = function(i,v) {
return setarg(i, v, POS_C, SIZE_C);
};
const GETARG_Bx = function(i) {
return i.Bx;
};
const SETARG_Bx = function(i,v) {
return setarg(i, v, POS_Bx, SIZE_Bx);
};
const GETARG_Ax = function(i) {
return i.Ax;
};
const SETARG_Ax = function(i,v) {
return setarg(i, v, POS_Ax, SIZE_Ax);
};
const GETARG_sBx = function(i) {
return i.sBx;
};
const SETARG_sBx = function(i, b) {
return SETARG_Bx(i, b + MAXARG_sBx);
};
/*
** Pre-calculate all possible part of the instruction
*/
const fullins = function(ins) {
if (typeof ins === "number") {
return {
code: ins,
opcode: (ins >> POS_OP) & MASK1(SIZE_OP, 0),
A: (ins >> POS_A) & MASK1(SIZE_A, 0),
B: (ins >> POS_B) & MASK1(SIZE_B, 0),
C: (ins >> POS_C) & MASK1(SIZE_C, 0),
Bx: (ins >> POS_Bx) & MASK1(SIZE_Bx, 0),
Ax: (ins >> POS_Ax) & MASK1(SIZE_Ax, 0),
sBx: ((ins >> POS_Bx) & MASK1(SIZE_Bx, 0)) - MAXARG_sBx
};
} else {
let i = ins.code;
ins.opcode = (i >> POS_OP) & MASK1(SIZE_OP, 0);
ins.A = (i >> POS_A) & MASK1(SIZE_A, 0);
ins.B = (i >> POS_B) & MASK1(SIZE_B, 0);
ins.C = (i >> POS_C) & MASK1(SIZE_C, 0);
ins.Bx = (i >> POS_Bx) & MASK1(SIZE_Bx, 0);
ins.Ax = (i >> POS_Ax) & MASK1(SIZE_Ax, 0);
ins.sBx = ((i >> POS_Bx) & MASK1(SIZE_Bx, 0)) - MAXARG_sBx;
return ins;
}
};
const CREATE_ABC = function(o, a, b, c) {
return fullins(o << POS_OP | a << POS_A | b << POS_B | c << POS_C);
};
const CREATE_ABx = function(o, a, bc) {
return fullins(o << POS_OP | a << POS_A | bc << POS_Bx);
};
const CREATE_Ax = function(o, a) {
return fullins(o << POS_OP | a << POS_Ax);
};
/* number of list items to accumulate before a SETLIST instruction */
const LFIELDS_PER_FLUSH = 50;
module.exports.BITRK = BITRK;
module.exports.CREATE_ABC = CREATE_ABC;
module.exports.CREATE_ABx = CREATE_ABx;
module.exports.CREATE_Ax = CREATE_Ax;
module.exports.GET_OPCODE = GET_OPCODE;
module.exports.GETARG_A = GETARG_A;
module.exports.GETARG_B = GETARG_B;
module.exports.GETARG_C = GETARG_C;
module.exports.GETARG_Bx = GETARG_Bx;
module.exports.GETARG_Ax = GETARG_Ax;
module.exports.GETARG_sBx = GETARG_sBx;
module.exports.INDEXK = INDEXK;
module.exports.ISK = ISK;
module.exports.LFIELDS_PER_FLUSH = LFIELDS_PER_FLUSH;
module.exports.MAXARG_A = MAXARG_A;
module.exports.MAXARG_Ax = MAXARG_Ax;
module.exports.MAXARG_B = MAXARG_B;
module.exports.MAXARG_Bx = MAXARG_Bx;
module.exports.MAXARG_C = MAXARG_C;
module.exports.MAXARG_sBx = MAXARG_sBx;
module.exports.MAXINDEXRK = MAXINDEXRK;
module.exports.NO_REG = NO_REG;
module.exports.OpArgK = OpArgK;
module.exports.OpArgN = OpArgN;
module.exports.OpArgR = OpArgR;
module.exports.OpArgU = OpArgU;
module.exports.OpCodes = OpCodes;
module.exports.OpCodesI = OpCodesI;
module.exports.POS_A = POS_A;
module.exports.POS_Ax = POS_Ax;
module.exports.POS_B = POS_B;
module.exports.POS_Bx = POS_Bx;
module.exports.POS_C = POS_C;
module.exports.POS_OP = POS_OP;
module.exports.RKASK = RKASK;
module.exports.SETARG_A = SETARG_A;
module.exports.SETARG_Ax = SETARG_Ax;
module.exports.SETARG_B = SETARG_B;
module.exports.SETARG_Bx = SETARG_Bx;
module.exports.SETARG_C = SETARG_C;
module.exports.SETARG_sBx = SETARG_sBx;
module.exports.SET_OPCODE = SET_OPCODE;
module.exports.SIZE_A = SIZE_A;
module.exports.SIZE_Ax = SIZE_Ax;
module.exports.SIZE_B = SIZE_B;
module.exports.SIZE_Bx = SIZE_Bx;
module.exports.SIZE_C = SIZE_C;
module.exports.SIZE_OP = SIZE_OP;
module.exports.fullins = fullins;
module.exports.getBMode = getBMode;
module.exports.getCMode = getCMode;
module.exports.getOpMode = getOpMode;
module.exports.iABC = iABC;
module.exports.iABx = iABx;
module.exports.iAsBx = iAsBx;
module.exports.iAx = iAx;
module.exports.testAMode = testAMode;
module.exports.testTMode = testTMode;
/***/ }),
/* 29 */
/***/ (function(module, exports) {
module.exports = function(module) {
if(!module.webpackPolyfill) {
module.deprecate = function() {};
module.paths = [];
// module.parent = undefined by default
if(!module.children) module.children = [];
Object.defineProperty(module, "loaded", {
enumerable: true,
get: function() {
return module.l;
}
});
Object.defineProperty(module, "id", {
enumerable: true,
get: function() {
return module.i;
}
});
module.webpackPolyfill = 1;
}
return module;
};
/***/ }),
/* 30 */
/***/ (function(module, exports) {
/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */
module.exports = __webpack_amd_options__;
/* WEBPACK VAR INJECTION */}.call(exports, {}))
/***/ }),
/* 31 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const lobject = __webpack_require__(7);
const ldo = __webpack_require__(13);
const lstate = __webpack_require__(25);
const lstring = __webpack_require__(17);
const ltable = __webpack_require__(16);
const ldebug = __webpack_require__(23);
const lvm = __webpack_require__(32);
const CT = defs.constant_types;
const luaT_typenames_ = [
"no value",
"nil",
"boolean",
"userdata",
"number",
"string",
"table",
"function",
"userdata",
"thread",
"proto" /* this last case is used for tests only */
].map(e => defs.to_luastring(e));
const ttypename = function(t) {
return luaT_typenames_[t + 1];
};
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER TM" and "ORDER OP"
*/
const TMS = {
TM_INDEX: 0,
TM_NEWINDEX: 1,
TM_GC: 2,
TM_MODE: 3,
TM_LEN: 4,
TM_EQ: 5, /* last tag method with fast access */
TM_ADD: 6,
TM_SUB: 7,
TM_MUL: 8,
TM_MOD: 9,
TM_POW: 10,
TM_DIV: 11,
TM_IDIV: 12,
TM_BAND: 13 ,
TM_BOR: 14,
TM_BXOR: 15,
TM_SHL: 16,
TM_SHR: 17,
TM_UNM: 18,
TM_BNOT: 19,
TM_LT: 20,
TM_LE: 21,
TM_CONCAT: 22,
TM_CALL: 23,
TM_N: 24 /* number of elements in the enum */
};
const luaT_init = function(L) {
L.l_G.tmname[TMS.TM_INDEX] = new lstring.luaS_new(L, defs.to_luastring("__index", true));
L.l_G.tmname[TMS.TM_NEWINDEX] = new lstring.luaS_new(L, defs.to_luastring("__newindex", true));
L.l_G.tmname[TMS.TM_GC] = new lstring.luaS_new(L, defs.to_luastring("__gc", true));
L.l_G.tmname[TMS.TM_MODE] = new lstring.luaS_new(L, defs.to_luastring("__mode", true));
L.l_G.tmname[TMS.TM_LEN] = new lstring.luaS_new(L, defs.to_luastring("__len", true));
L.l_G.tmname[TMS.TM_EQ] = new lstring.luaS_new(L, defs.to_luastring("__eq", true));
L.l_G.tmname[TMS.TM_ADD] = new lstring.luaS_new(L, defs.to_luastring("__add", true));
L.l_G.tmname[TMS.TM_SUB] = new lstring.luaS_new(L, defs.to_luastring("__sub", true));
L.l_G.tmname[TMS.TM_MUL] = new lstring.luaS_new(L, defs.to_luastring("__mul", true));
L.l_G.tmname[TMS.TM_MOD] = new lstring.luaS_new(L, defs.to_luastring("__mod", true));
L.l_G.tmname[TMS.TM_POW] = new lstring.luaS_new(L, defs.to_luastring("__pow", true));
L.l_G.tmname[TMS.TM_DIV] = new lstring.luaS_new(L, defs.to_luastring("__div", true));
L.l_G.tmname[TMS.TM_IDIV] = new lstring.luaS_new(L, defs.to_luastring("__idiv", true));
L.l_G.tmname[TMS.TM_BAND] = new lstring.luaS_new(L, defs.to_luastring("__band", true));
L.l_G.tmname[TMS.TM_BOR] = new lstring.luaS_new(L, defs.to_luastring("__bor", true));
L.l_G.tmname[TMS.TM_BXOR] = new lstring.luaS_new(L, defs.to_luastring("__bxor", true));
L.l_G.tmname[TMS.TM_SHL] = new lstring.luaS_new(L, defs.to_luastring("__shl", true));
L.l_G.tmname[TMS.TM_SHR] = new lstring.luaS_new(L, defs.to_luastring("__shr", true));
L.l_G.tmname[TMS.TM_UNM] = new lstring.luaS_new(L, defs.to_luastring("__unm", true));
L.l_G.tmname[TMS.TM_BNOT] = new lstring.luaS_new(L, defs.to_luastring("__bnot", true));
L.l_G.tmname[TMS.TM_LT] = new lstring.luaS_new(L, defs.to_luastring("__lt", true));
L.l_G.tmname[TMS.TM_LE] = new lstring.luaS_new(L, defs.to_luastring("__le", true));
L.l_G.tmname[TMS.TM_CONCAT] = new lstring.luaS_new(L, defs.to_luastring("__concat", true));
L.l_G.tmname[TMS.TM_CALL] = new lstring.luaS_new(L, defs.to_luastring("__call", true));
};
/*
** Return the name of the type of an object. For tables and userdata
** with metatable, use their '__name' metafield, if present.
*/
const __name = defs.to_luastring('__name', true);
const luaT_objtypename = function(L, o) {
let mt;
if ((o.ttistable() && (mt = o.value.metatable) !== null) ||
(o.ttisfulluserdata() && (mt = o.value.metatable) !== null)) {
let name = ltable.luaH_getstr(mt, lstring.luaS_bless(L, __name));
if (name.ttisstring())
return name.svalue();
}
return ttypename(o.ttnov());
};
const luaT_callTM = function(L, f, p1, p2, p3, hasres) {
let func = L.top;
lobject.pushobj2s(L, f); /* push function (assume EXTRA_STACK) */
lobject.pushobj2s(L, p1); /* 1st argument */
lobject.pushobj2s(L, p2); /* 2nd argument */
if (!hasres) /* no result? 'p3' is third argument */
lobject.pushobj2s(L, p3); /* 3rd argument */
if (L.ci.callstatus & lstate.CIST_LUA)
ldo.luaD_call(L, func, hasres);
else
ldo.luaD_callnoyield(L, func, hasres);
if (hasres) { /* if has result, move it to its place */
let tv = L.stack[L.top-1];
delete L.stack[--L.top];
p3.setfrom(tv);
}
};
const luaT_callbinTM = function(L, p1, p2, res, event) {
let tm = luaT_gettmbyobj(L, p1, event);
if (tm.ttisnil())
tm = luaT_gettmbyobj(L, p2, event);
if (tm.ttisnil()) return false;
luaT_callTM(L, tm, p1, p2, res, 1);
return true;
};
const luaT_trybinTM = function(L, p1, p2, res, event) {
if (!luaT_callbinTM(L, p1, p2, res, event)) {
switch (event) {
case TMS.TM_CONCAT:
ldebug.luaG_concaterror(L, p1, p2);
case TMS.TM_BAND: case TMS.TM_BOR: case TMS.TM_BXOR:
case TMS.TM_SHL: case TMS.TM_SHR: case TMS.TM_BNOT: {
let n1 = lvm.tonumber(p1);
let n2 = lvm.tonumber(p2);
if (n1 !== false && n2 !== false)
ldebug.luaG_tointerror(L, p1, p2);
else
ldebug.luaG_opinterror(L, p1, p2, defs.to_luastring("perform bitwise operation on", true));
}
default:
ldebug.luaG_opinterror(L, p1, p2, defs.to_luastring("perform arithmetic on", true));
}
}
};
const luaT_callorderTM = function(L, p1, p2, event) {
let res = new lobject.TValue();
if (!luaT_callbinTM(L, p1, p2, res, event))
return null;
else
return !res.l_isfalse();
};
const fasttm = function(l, et, e) {
return et === null ? null :
(et.flags & (1 << e)) ? null : luaT_gettm(et, e, l.l_G.tmname[e]);
};
const luaT_gettm = function(events, event, ename) {
const tm = ltable.luaH_getstr(events, ename);
assert(event <= TMS.TM_EQ);
if (tm.ttisnil()) { /* no tag method? */
events.flags |= 1<<event; /* cache this fact */
return null;
}
else return tm;
};
const luaT_gettmbyobj = function(L, o, event) {
let mt;
switch(o.ttnov()) {
case CT.LUA_TTABLE:
case CT.LUA_TUSERDATA:
mt = o.value.metatable;
break;
default:
mt = L.l_G.mt[o.ttnov()];
}
return mt ? ltable.luaH_getstr(mt, L.l_G.tmname[event]) : lobject.luaO_nilobject;
};
module.exports.fasttm = fasttm;
module.exports.TMS = TMS;
module.exports.luaT_callTM = luaT_callTM;
module.exports.luaT_callbinTM = luaT_callbinTM;
module.exports.luaT_trybinTM = luaT_trybinTM;
module.exports.luaT_callorderTM = luaT_callorderTM;
module.exports.luaT_gettm = luaT_gettm;
module.exports.luaT_gettmbyobj = luaT_gettmbyobj;
module.exports.luaT_init = luaT_init;
module.exports.luaT_objtypename = luaT_objtypename;
module.exports.ttypename = ttypename;
/***/ }),
/* 32 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const lopcodes = __webpack_require__(33);
const luaconf = __webpack_require__(22);
const lobject = __webpack_require__(7);
const lfunc = __webpack_require__(24);
const lstate = __webpack_require__(25);
const lstring = __webpack_require__(17);
const llimit = __webpack_require__(10);
const ldo = __webpack_require__(13);
const ltm = __webpack_require__(31);
const ltable = __webpack_require__(16);
const ldebug = __webpack_require__(23);
const CT = defs.constant_types;
const LUA_MULTRET = defs.LUA_MULTRET;
/*
** finish execution of an opcode interrupted by an yield
*/
const luaV_finishOp = function(L) {
let ci = L.ci;
let OCi = lopcodes.OpCodesI;
let base = ci.l_base;
let inst = ci.l_code[ci.l_savedpc - 1]; /* interrupted instruction */
let op = inst.opcode;
switch (op) { /* finish its execution */
case OCi.OP_ADD: case OCi.OP_SUB: case OCi.OP_MUL: case OCi.OP_DIV: case OCi.OP_IDIV:
case OCi.OP_BAND: case OCi.OP_BOR: case OCi.OP_BXOR: case OCi.OP_SHL: case OCi.OP_SHR:
case OCi.OP_MOD: case OCi.OP_POW:
case OCi.OP_UNM: case OCi.OP_BNOT: case OCi.OP_LEN:
case OCi.OP_GETTABUP: case OCi.OP_GETTABLE: case OCi.OP_SELF: {
lobject.setobjs2s(L, base + inst.A, L.top-1);
delete L.stack[--L.top];
break;
}
case OCi.OP_LE: case OCi.OP_LT: case OCi.OP_EQ: {
let res = !L.stack[L.top - 1].l_isfalse();
delete L.stack[--L.top];
if (ci.callstatus & lstate.CIST_LEQ) { /* "<=" using "<" instead? */
assert(op === OCi.OP_LE);
ci.callstatus ^= lstate.CIST_LEQ; /* clear mark */
res = !res; /* negate result */
}
assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_JMP);
if (res !== (inst.A ? true : false)) /* condition failed? */
ci.l_savedpc++; /* skip jump instruction */
break;
}
case OCi.OP_CONCAT: {
let top = L.top - 1; /* top when 'luaT_trybinTM' was called */
let b = inst.B; /* first element to concatenate */
let total = top - 1 - (base + b); /* yet to concatenate */
lobject.setobjs2s(L, top - 2, top); /* put TM result in proper position */
if (total > 1) { /* are there elements to concat? */
L.top = top - 1; /* top is one after last element (at top-2) */
luaV_concat(L, total); /* concat them (may yield again) */
}
/* move final result to final position */
lobject.setobjs2s(L, ci.l_base + inst.A, L.top - 1);
ldo.adjust_top(L, ci.top); /* restore top */
break;
}
case OCi.OP_TFORCALL: {
assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_TFORLOOP);
ldo.adjust_top(L, ci.top); /* correct top */
break;
}
case OCi.OP_CALL: {
if (inst.C - 1 >= 0) /* nresults >= 0? */
ldo.adjust_top(L, ci.top); /* adjust results */
break;
}
}
};
const RA = function(L, base, i) {
return base + i.A;
};
const RB = function(L, base, i) {
return base + i.B;
};
const RC = function(L, base, i) {
return base + i.C;
};
const RKB = function(L, base, k, i) {
return lopcodes.ISK(i.B) ? k[lopcodes.INDEXK(i.B)] : L.stack[base + i.B];
};
const RKC = function(L, base, k, i) {
return lopcodes.ISK(i.C) ? k[lopcodes.INDEXK(i.C)] : L.stack[base + i.C];
};
const luaV_execute = function(L) {
const OCi = lopcodes.OpCodesI;
let ci = L.ci;
ci.callstatus |= lstate.CIST_FRESH;
newframe:
for (;;) {
assert(ci === L.ci);
let cl = ci.func.value;
let k = cl.p.k;
let base = ci.l_base;
let i = ci.l_code[ci.l_savedpc++];
if (L.hookmask & (defs.LUA_MASKLINE | defs.LUA_MASKCOUNT)) {
ldebug.luaG_traceexec(L);
}
let ra = RA(L, base, i);
let opcode = i.opcode;
switch (opcode) {
case OCi.OP_MOVE: {
lobject.setobjs2s(L, ra, RB(L, base, i));
break;
}
case OCi.OP_LOADK: {
let konst = k[i.Bx];
lobject.setobj2s(L, ra, konst);
break;
}
case OCi.OP_LOADKX: {
assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_EXTRAARG);
let konst = k[ci.l_code[ci.l_savedpc++].Ax];
lobject.setobj2s(L, ra, konst);
break;
}
case OCi.OP_LOADBOOL: {
L.stack[ra].setbvalue(i.B !== 0);
if (i.C !== 0)
ci.l_savedpc++; /* skip next instruction (if C) */
break;
}
case OCi.OP_LOADNIL: {
for (let j = 0; j <= i.B; j++)
L.stack[ra + j].setnilvalue();
break;
}
case OCi.OP_GETUPVAL: {
let b = i.B;
lobject.setobj2s(L, ra, cl.upvals[b].v);
break;
}
case OCi.OP_GETTABUP: {
let upval = cl.upvals[i.B].v;
let rc = RKC(L, base, k, i);
luaV_gettable(L, upval, rc, ra);
break;
}
case OCi.OP_GETTABLE: {
let rb = L.stack[RB(L, base, i)];
let rc = RKC(L, base, k, i);
luaV_gettable(L, rb, rc, ra);
break;
}
case OCi.OP_SETTABUP: {
let upval = cl.upvals[i.A].v;
let rb = RKB(L, base, k, i);
let rc = RKC(L, base, k, i);
settable(L, upval, rb, rc);
break;
}
case OCi.OP_SETUPVAL: {
let uv = cl.upvals[i.B];
uv.v.setfrom(L.stack[ra]);
break;
}
case OCi.OP_SETTABLE: {
let table = L.stack[ra];
let key = RKB(L, base, k, i);
let v = RKC(L, base, k, i);
settable(L, table, key, v);
break;
}
case OCi.OP_NEWTABLE: {
L.stack[ra].sethvalue(ltable.luaH_new(L));
break;
}
case OCi.OP_SELF: {
let rb = RB(L, base, i);
let rc = RKC(L, base, k, i);
lobject.setobjs2s(L, ra + 1, rb);
luaV_gettable(L, L.stack[rb], rc, ra);
break;
}
case OCi.OP_ADD: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if (op1.ttisinteger() && op2.ttisinteger()) {
L.stack[ra].setivalue((op1.value + op2.value)|0);
} else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(numberop1 + numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_ADD);
}
break;
}
case OCi.OP_SUB: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if (op1.ttisinteger() && op2.ttisinteger()) {
L.stack[ra].setivalue((op1.value - op2.value)|0);
} else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(numberop1 - numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_SUB);
}
break;
}
case OCi.OP_MUL: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if (op1.ttisinteger() && op2.ttisinteger()) {
L.stack[ra].setivalue(Math.imul(op1.value, op2.value));
} else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(numberop1 * numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_MUL);
}
break;
}
case OCi.OP_MOD: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if (op1.ttisinteger() && op2.ttisinteger()) {
L.stack[ra].setivalue(luaV_mod(L, op1.value, op2.value));
} else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(llimit.luai_nummod(L, numberop1, numberop2));
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_MOD);
}
break;
}
case OCi.OP_POW: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(Math.pow(numberop1, numberop2));
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_POW);
}
break;
}
case OCi.OP_DIV: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(numberop1 / numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_DIV);
}
break;
}
case OCi.OP_IDIV: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if (op1.ttisinteger() && op2.ttisinteger()) {
L.stack[ra].setivalue(luaV_div(L, op1.value, op2.value));
} else if ((numberop1 = tonumber(op1)) !== false && (numberop2 = tonumber(op2)) !== false) {
L.stack[ra].setfltvalue(Math.floor(numberop1 / numberop2));
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_IDIV);
}
break;
}
case OCi.OP_BAND: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tointeger(op1)) !== false && (numberop2 = tointeger(op2)) !== false) {
L.stack[ra].setivalue(numberop1 & numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_BAND);
}
break;
}
case OCi.OP_BOR: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tointeger(op1)) !== false && (numberop2 = tointeger(op2)) !== false) {
L.stack[ra].setivalue(numberop1 | numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_BOR);
}
break;
}
case OCi.OP_BXOR: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tointeger(op1)) !== false && (numberop2 = tointeger(op2)) !== false) {
L.stack[ra].setivalue(numberop1 ^ numberop2);
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_BXOR);
}
break;
}
case OCi.OP_SHL: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tointeger(op1)) !== false && (numberop2 = tointeger(op2)) !== false) {
L.stack[ra].setivalue(luaV_shiftl(numberop1, numberop2));
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_SHL);
}
break;
}
case OCi.OP_SHR: {
let op1 = RKB(L, base, k, i);
let op2 = RKC(L, base, k, i);
let numberop1, numberop2;
if ((numberop1 = tointeger(op1)) !== false && (numberop2 = tointeger(op2)) !== false) {
L.stack[ra].setivalue(luaV_shiftl(numberop1, -numberop2));
} else {
ltm.luaT_trybinTM(L, op1, op2, L.stack[ra], ltm.TMS.TM_SHR);
}
break;
}
case OCi.OP_UNM: {
let op = L.stack[RB(L, base, i)];
let numberop;
if (op.ttisinteger()) {
L.stack[ra].setivalue((-op.value)|0);
} else if ((numberop = tonumber(op)) !== false) {
L.stack[ra].setfltvalue(-numberop);
} else {
ltm.luaT_trybinTM(L, op, op, L.stack[ra], ltm.TMS.TM_UNM);
}
break;
}
case OCi.OP_BNOT: {
let op = L.stack[RB(L, base, i)];
if (op.ttisinteger()) {
L.stack[ra].setivalue(~op.value);
} else {
ltm.luaT_trybinTM(L, op, op, L.stack[ra], ltm.TMS.TM_BNOT);
}
break;
}
case OCi.OP_NOT: {
let op = L.stack[RB(L, base, i)];
L.stack[ra].setbvalue(op.l_isfalse());
break;
}
case OCi.OP_LEN: {
luaV_objlen(L, L.stack[ra], L.stack[RB(L, base, i)]);
break;
}
case OCi.OP_CONCAT: {
let b = i.B;
let c = i.C;
L.top = base + c + 1; /* mark the end of concat operands */
luaV_concat(L, c - b + 1);
let rb = base + b;
lobject.setobjs2s(L, ra, rb);
ldo.adjust_top(L, ci.top); /* restore top */
break;
}
case OCi.OP_JMP: {
dojump(L, ci, i, 0);
break;
}
case OCi.OP_EQ: {
if (luaV_equalobj(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A)
ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_LT: {
if (luaV_lessthan(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A)
ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_LE: {
if (luaV_lessequal(L, RKB(L, base, k, i), RKC(L, base, k, i)) !== i.A)
ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_TEST: {
if (i.C ? L.stack[ra].l_isfalse() : !L.stack[ra].l_isfalse())
ci.l_savedpc++;
else
donextjump(L, ci);
break;
}
case OCi.OP_TESTSET: {
let rbIdx = RB(L, base, i);
let rb = L.stack[rbIdx];
if (i.C ? rb.l_isfalse() : !rb.l_isfalse())
ci.l_savedpc++;
else {
lobject.setobjs2s(L, ra, rbIdx);
donextjump(L, ci);
}
break;
}
case OCi.OP_CALL: {
let b = i.B;
let nresults = i.C - 1;
if (b !== 0) ldo.adjust_top(L, ra+b); /* else previous instruction set top */
if (ldo.luaD_precall(L, ra, nresults)) {
if (nresults >= 0)
ldo.adjust_top(L, ci.top); /* adjust results */
} else {
ci = L.ci;
continue newframe;
}
break;
}
case OCi.OP_TAILCALL: {
let b = i.B;
if (b !== 0) ldo.adjust_top(L, ra+b); /* else previous instruction set top */
if (ldo.luaD_precall(L, ra, LUA_MULTRET)) { // JS function
} else {
/* tail call: put called frame (n) in place of caller one (o) */
let nci = L.ci;
let oci = nci.previous;
let nfunc = nci.func;
let nfuncOff = nci.funcOff;
let ofuncOff = oci.funcOff;
let lim = nci.l_base + nfunc.value.p.numparams;
if (cl.p.p.length > 0) lfunc.luaF_close(L, oci.l_base);
for (let aux = 0; nfuncOff + aux < lim; aux++)
lobject.setobjs2s(L, ofuncOff + aux, nfuncOff + aux);
oci.l_base = ofuncOff + (nci.l_base - nfuncOff);
oci.top = ofuncOff + (L.top - nfuncOff);
ldo.adjust_top(L, oci.top); /* correct top */
oci.l_code = nci.l_code;
oci.l_savedpc = nci.l_savedpc;
oci.callstatus |= lstate.CIST_TAIL;
oci.next = null;
ci = L.ci = oci;
assert(L.top === oci.l_base + L.stack[ofuncOff].value.p.maxstacksize);
continue newframe;
}
break;
}
case OCi.OP_RETURN: {
if (cl.p.p.length > 0) lfunc.luaF_close(L, base);
let b = ldo.luaD_poscall(L, ci, ra, (i.B !== 0 ? i.B - 1 : L.top - ra));
if (ci.callstatus & lstate.CIST_FRESH)
return; /* external invocation: return */
/* invocation via reentry: continue execution */
ci = L.ci;
if (b) ldo.adjust_top(L, ci.top);
assert(ci.callstatus & lstate.CIST_LUA);
assert(ci.l_code[ci.l_savedpc - 1].opcode === OCi.OP_CALL);
continue newframe;
}
case OCi.OP_FORLOOP: {
if (L.stack[ra].ttisinteger()) { /* integer loop? */
let step = L.stack[ra + 2].value;
let idx = (L.stack[ra].value + step)|0;
let limit = L.stack[ra + 1].value;
if (0 < step ? idx <= limit : limit <= idx) {
ci.l_savedpc += i.sBx;
L.stack[ra].chgivalue(idx); /* update internal index... */
L.stack[ra + 3].setivalue(idx);
}
} else { /* floating loop */
let step = L.stack[ra + 2].value;
let idx = L.stack[ra].value + step;
let limit = L.stack[ra + 1].value;
if (0 < step ? idx <= limit : limit <= idx) {
ci.l_savedpc += i.sBx;
L.stack[ra].chgfltvalue(idx); /* update internal index... */
L.stack[ra + 3].setfltvalue(idx);
}
}
break;
}
case OCi.OP_FORPREP: {
let init = L.stack[ra];
let plimit = L.stack[ra + 1];
let pstep = L.stack[ra + 2];
let forlim;
if (init.ttisinteger() && pstep.ttisinteger() && (forlim = forlimit(plimit, pstep.value))) {
/* all values are integer */
let initv = forlim.stopnow ? 0 : init.value;
plimit.value = forlim.ilimit;
init.value = (initv - pstep.value)|0;
} else { /* try making all values floats */
let nlimit, nstep, ninit;
if ((nlimit = tonumber(plimit)) === false)
ldebug.luaG_runerror(L, defs.to_luastring("'for' limit must be a number", true));
L.stack[ra + 1].setfltvalue(nlimit);
if ((nstep = tonumber(pstep)) === false)
ldebug.luaG_runerror(L, defs.to_luastring("'for' step must be a number", true));
L.stack[ra + 2].setfltvalue(nstep);
if ((ninit = tonumber(init)) === false)
ldebug.luaG_runerror(L, defs.to_luastring("'for' initial value must be a number", true));
L.stack[ra].setfltvalue(ninit - nstep);
}
ci.l_savedpc += i.sBx;
break;
}
case OCi.OP_TFORCALL: {
let cb = ra + 3; /* call base */
lobject.setobjs2s(L, cb+2, ra+2);
lobject.setobjs2s(L, cb+1, ra+1);
lobject.setobjs2s(L, cb, ra);
ldo.adjust_top(L, cb+3); /* func. + 2 args (state and index) */
ldo.luaD_call(L, cb, i.C);
ldo.adjust_top(L, ci.top);
/* go straight to OP_TFORLOOP */
i = ci.l_code[ci.l_savedpc++];
ra = RA(L, base, i);
assert(i.opcode === OCi.OP_TFORLOOP);
}
/* fall through */
case OCi.OP_TFORLOOP: {
if (!L.stack[ra + 1].ttisnil()) { /* continue loop? */
lobject.setobjs2s(L, ra, ra + 1); /* save control variable */
ci.l_savedpc += i.sBx; /* jump back */
}
break;
}
case OCi.OP_SETLIST: {
let n = i.B;
let c = i.C;
if (n === 0) n = L.top - ra - 1;
if (c === 0) {
assert(ci.l_code[ci.l_savedpc].opcode === OCi.OP_EXTRAARG);
c = ci.l_code[ci.l_savedpc++].Ax;
}
let h = L.stack[ra].value;
let last = ((c - 1) * lopcodes.LFIELDS_PER_FLUSH) + n;
for (; n > 0; n--) {
ltable.luaH_setint(h, last--, L.stack[ra + n]);
}
ldo.adjust_top(L, ci.top); /* correct top (in case of previous open call) */
break;
}
case OCi.OP_CLOSURE: {
let p = cl.p.p[i.Bx];
let ncl = getcached(p, cl.upvals, L.stack, base); /* cached closure */
if (ncl === null) /* no match? */
pushclosure(L, p, cl.upvals, base, ra); /* create a new one */
else
L.stack[ra].setclLvalue(ncl);
break;
}
case OCi.OP_VARARG: {
let b = i.B - 1;
let n = base - ci.funcOff - cl.p.numparams - 1;
let j;
if (n < 0) /* less arguments than parameters? */
n = 0; /* no vararg arguments */
if (b < 0) {
b = n; /* get all var. arguments */
ldo.luaD_checkstack(L, n);
ldo.adjust_top(L, ra + n);
}
for (j = 0; j < b && j < n; j++)
lobject.setobjs2s(L, ra + j, base - n + j);
for (; j < b; j++) /* complete required results with nil */
L.stack[ra + j].setnilvalue();
break;
}
case OCi.OP_EXTRAARG: {
throw Error("invalid opcode");
}
}
}
};
const dojump = function(L, ci, i, e) {
let a = i.A;
if (a !== 0) lfunc.luaF_close(L, ci.l_base + a - 1);
ci.l_savedpc += i.sBx + e;
};
const donextjump = function(L, ci) {
dojump(L, ci, ci.l_code[ci.l_savedpc], 1);
};
const luaV_lessthan = function(L, l, r) {
if (l.ttisnumber() && r.ttisnumber())
return LTnum(l, r) ? 1 : 0;
else if (l.ttisstring() && r.ttisstring())
return l_strcmp(l.tsvalue(), r.tsvalue()) < 0 ? 1 : 0;
else {
let res = ltm.luaT_callorderTM(L, l, r, ltm.TMS.TM_LT);
if (res === null)
ldebug.luaG_ordererror(L, l, r);
return res ? 1 : 0;
}
};
const luaV_lessequal = function(L, l, r) {
let res;
if (l.ttisnumber() && r.ttisnumber())
return LEnum(l, r) ? 1 : 0;
else if (l.ttisstring() && r.ttisstring())
return l_strcmp(l.tsvalue(), r.tsvalue()) <= 0 ? 1 : 0;
else {
res = ltm.luaT_callorderTM(L, l, r, ltm.TMS.TM_LE);
if (res !== null)
return res ? 1 : 0;
}
/* try 'lt': */
L.ci.callstatus |= lstate.CIST_LEQ; /* mark it is doing 'lt' for 'le' */
res = ltm.luaT_callorderTM(L, r, l, ltm.TMS.TM_LT);
L.ci.callstatus ^= lstate.CIST_LEQ; /* clear mark */
if (res === null)
ldebug.luaG_ordererror(L, l, r);
return res ? 0 : 1; /* result is negated */
};
const luaV_equalobj = function(L, t1, t2) {
if (t1.ttype() !== t2.ttype()) { /* not the same variant? */
if (t1.ttnov() !== t2.ttnov() || t1.ttnov() !== CT.LUA_TNUMBER)
return 0; /* only numbers can be equal with different variants */
else { /* two numbers with different variants */
/* OPTIMIZATION: instead of calling luaV_tointeger we can just let JS do the comparison */
return (t1.value === t2.value) ? 1 : 0;
}
}
let tm;
/* values have same type and same variant */
switch(t1.ttype()) {
case CT.LUA_TNIL:
return 1;
case CT.LUA_TBOOLEAN:
return t1.value == t2.value ? 1 : 0; // Might be 1 or true
case CT.LUA_TLIGHTUSERDATA:
case CT.LUA_TNUMINT:
case CT.LUA_TNUMFLT:
case CT.LUA_TLCF:
return t1.value === t2.value ? 1 : 0;
case CT.LUA_TSHRSTR:
case CT.LUA_TLNGSTR: {
return lstring.luaS_eqlngstr(t1.tsvalue(), t2.tsvalue()) ? 1 : 0;
}
case CT.LUA_TUSERDATA:
case CT.LUA_TTABLE:
if (t1.value === t2.value) return 1;
else if (L === null) return 0;
tm = ltm.fasttm(L, t1.value.metatable, ltm.TMS.TM_EQ);
if (tm === null)
tm = ltm.fasttm(L, t2.value.metatable, ltm.TMS.TM_EQ);
break;
default:
return t1.value === t2.value ? 1 : 0;
}
if (tm === null) /* no TM? */
return 0;
let tv = new lobject.TValue(); /* doesn't use the stack */
ltm.luaT_callTM(L, tm, t1, t2, tv, 1);
return tv.l_isfalse() ? 0 : 1;
};
const luaV_rawequalobj = function(t1, t2) {
return luaV_equalobj(null, t1, t2);
};
const forlimit = function(obj, step) {
let stopnow = false;
let ilimit = luaV_tointeger(obj, step < 0 ? 2 : 1);
if (ilimit === false) {
let n = tonumber(obj);
if (n === false)
return false;
if (0 < n) {
ilimit = llimit.LUA_MAXINTEGER;
if (step < 0) stopnow = true;
} else {
ilimit = llimit.LUA_MININTEGER;
if (step >= 0) stopnow = true;
}
}
return {
stopnow: stopnow,
ilimit: ilimit
};
};
/*
** try to convert a value to an integer, rounding according to 'mode':
** mode === 0: accepts only integral values
** mode === 1: takes the floor of the number
** mode === 2: takes the ceil of the number
*/
const luaV_tointeger = function(obj, mode) {
if (obj.ttisfloat()) {
let n = obj.value;
let f = Math.floor(n);
if (n !== f) { /* not an integral value? */
if (mode === 0)
return false; /* fails if mode demands integral value */
else if (mode > 1) /* needs ceil? */
f += 1; /* convert floor to ceil (remember: n !== f) */
}
return luaconf.lua_numbertointeger(f);
} else if (obj.ttisinteger()) {
return obj.value;
} else if (cvt2num(obj)) {
let v = lobject.luaO_str2num(obj.svalue());
if (v !== false)
return luaV_tointeger(v, mode);
}
return false;
};
const tointeger = function(o) {
return o.ttisinteger() ? o.value : luaV_tointeger(o, 0);
};
const tonumber = function(o) {
if (o.ttnov() === CT.LUA_TNUMBER)
return o.value;
if (cvt2num(o)) { /* string convertible to number? */
let v = lobject.luaO_str2num(o.svalue());
if (v !== false)
return v.value;
}
return false;
};
/*
** Return 'l < r', for numbers.
** As fengari uses javascript numbers for both floats and integers and has
** correct semantics, we can just compare values.
*/
const LTnum = function(l, r) {
return l.value < r.value;
};
/*
** Return 'l <= r', for numbers.
*/
const LEnum = function(l, r) {
return l.value <= r.value;
};
/*
** Compare two strings 'ls' x 'rs', returning an integer smaller-equal-
** -larger than zero if 'ls' is smaller-equal-larger than 'rs'.
*/
const l_strcmp = function(ls, rs) {
let l = lstring.luaS_hashlongstr(ls);
let r = lstring.luaS_hashlongstr(rs);
/* In fengari we assume string hash has same collation as byte values */
if (l === r)
return 0;
else if (l < r)
return -1;
else
return 1;
};
/*
** Main operation 'ra' = #rb'.
*/
const luaV_objlen = function(L, ra, rb) {
let tm;
switch(rb.ttype()) {
case CT.LUA_TTABLE: {
let h = rb.value;
tm = ltm.fasttm(L, h.metatable, ltm.TMS.TM_LEN);
if (tm !== null) break; /* metamethod? break switch to call it */
ra.setivalue(ltable.luaH_getn(h)); /* else primitive len */
return;
}
case CT.LUA_TSHRSTR:
case CT.LUA_TLNGSTR:
ra.setivalue(rb.vslen());
return;
default: {
tm = ltm.luaT_gettmbyobj(L, rb, ltm.TMS.TM_LEN);
if (tm.ttisnil())
ldebug.luaG_typeerror(L, rb, defs.to_luastring("get length of", true));
break;
}
}
ltm.luaT_callTM(L, tm, rb, rb, ra, 1);
};
const luaV_div = function(L, m, n) {
if (n === 0)
ldebug.luaG_runerror(L, defs.to_luastring("attempt to divide by zero"));
return Math.floor(m / n)|0;
};
// % semantic on negative numbers is different in js
const luaV_mod = function(L, m, n) {
if (n === 0)
ldebug.luaG_runerror(L, defs.to_luastring("attempt to perform 'n%%0'"));
return (m - Math.floor(m / n) * n)|0;
};
const NBITS = 32;
const luaV_shiftl = function(x, y) {
if (y < 0) { /* shift right? */
if (y <= -NBITS) return 0;
else return x >>> -y;
}
else { /* shift left */
if (y >= NBITS) return 0;
else return x << y;
}
};
/*
** check whether cached closure in prototype 'p' may be reused, that is,
** whether there is a cached closure with the same upvalues needed by
** new closure to be created.
*/
const getcached = function(p, encup, stack, base) {
let c = p.cache;
if (c !== null) { /* is there a cached closure? */
let uv = p.upvalues;
let nup = uv.length;
for (let i = 0; i < nup; i++) { /* check whether it has right upvalues */
let v = uv[i].instack ? stack[base + uv[i].idx] : encup[uv[i].idx].v;
if (c.upvals[i].v !== v)
return null; /* wrong upvalue; cannot reuse closure */
}
}
return c; /* return cached closure (or NULL if no cached closure) */
};
/*
** create a new Lua closure, push it in the stack, and initialize
** its upvalues.
*/
const pushclosure = function(L, p, encup, base, ra) {
let nup = p.upvalues.length;
let uv = p.upvalues;
let ncl = new lobject.LClosure(L, nup);
ncl.p = p;
L.stack[ra].setclLvalue(ncl);
for (let i = 0; i < nup; i++) {
if (uv[i].instack)
ncl.upvals[i] = lfunc.luaF_findupval(L, base + uv[i].idx);
else
ncl.upvals[i] = encup[uv[i].idx];
ncl.upvals[i].refcount++;
}
p.cache = ncl; /* save it on cache for reuse */
};
const cvt2str = function(o) {
return o.ttisnumber();
};
const cvt2num = function(o) {
return o.ttisstring();
};
const tostring = function(L, i) {
let o = L.stack[i];
if (o.ttisstring()) return true;
if (cvt2str(o)) {
lobject.luaO_tostring(L, o);
return true;
}
return false;
};
const isemptystr = function(o) {
return o.ttisstring() && o.vslen() === 0;
};
/*
** Main operation for concatenation: concat 'total' values in the stack,
** from 'L->top - total' up to 'L->top - 1'.
*/
const luaV_concat = function(L, total) {
assert(total >= 2);
do {
let top = L.top;
let n = 2; /* number of elements handled in this pass (at least 2) */
if (!(L.stack[top-2].ttisstring() || cvt2str(L.stack[top-2])) || !tostring(L, top - 1)) {
ltm.luaT_trybinTM(L, L.stack[top-2], L.stack[top-1], L.stack[top-2], ltm.TMS.TM_CONCAT);
} else if (isemptystr(L.stack[top-1])) {
tostring(L, top - 2);
} else if (isemptystr(L.stack[top-2])) {
lobject.setobjs2s(L, top - 2, top - 1);
} else {
/* at least two non-empty string values; get as many as possible */
let toconcat = new Array(total);
toconcat[total-1] = L.stack[top-1].svalue();
for (n = 1; n < total; n++) {
if (!tostring(L, top - n - 1)) {
toconcat = toconcat.slice(total-n);
break;
}
toconcat[total-n-1] = L.stack[top - n - 1].svalue();
}
let ts = lstring.luaS_bless(L, Array.prototype.concat.apply([], toconcat));
lobject.setsvalue2s(L, top - n, ts);
}
total -= n - 1; /* got 'n' strings to create 1 new */
/* popped 'n' strings and pushed one */
for (; L.top > top-(n-1);)
delete L.stack[--L.top];
} while (total > 1); /* repeat until only 1 result left */
};
const MAXTAGLOOP = 2000;
const luaV_gettable = function(L, t, key, ra) {
for (let loop = 0; loop < MAXTAGLOOP; loop++) {
let tm;
if (!t.ttistable()) {
tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_INDEX);
if (tm.ttisnil())
ldebug.luaG_typeerror(L, t, defs.to_luastring('index', true)); /* no metamethod */
/* else will try the metamethod */
} else {
let slot = ltable.luaH_get(L, t.value, key);
if (!slot.ttisnil()) {
lobject.setobj2s(L, ra, slot);
return;
} else { /* 't' is a table */
tm = ltm.fasttm(L, t.value.metatable, ltm.TMS.TM_INDEX); /* table's metamethod */
if (tm === null) { /* no metamethod? */
L.stack[ra].setnilvalue(); /* result is nil */
return;
}
}
/* else will try the metamethod */
}
if (tm.ttisfunction()) { /* is metamethod a function? */
ltm.luaT_callTM(L, tm, t, key, L.stack[ra], 1); /* call it */
return;
}
t = tm; /* else try to access 'tm[key]' */
}
ldebug.luaG_runerror(L, defs.to_luastring("'__index' chain too long; possible loop", true));
};
const settable = function(L, t, key, val) {
for (let loop = 0; loop < MAXTAGLOOP; loop++) {
let tm;
if (t.ttistable()) {
let h = t.value; /* save 't' table */
let slot = ltable.luaH_set(L, h, key);
if (!slot.ttisnil() || (tm = ltm.fasttm(L, h.metatable, ltm.TMS.TM_NEWINDEX)) === null) {
if (val.ttisnil())
ltable.luaH_delete(L, h, key);
else
slot.setfrom(val);
ltable.invalidateTMcache(h);
return;
}
/* else will try the metamethod */
} else { /* not a table; check metamethod */
if ((tm = ltm.luaT_gettmbyobj(L, t, ltm.TMS.TM_NEWINDEX)).ttisnil())
ldebug.luaG_typeerror(L, t, defs.to_luastring('index', true));
}
/* try the metamethod */
if (tm.ttisfunction()) {
ltm.luaT_callTM(L, tm, t, key, val, 0);
return;
}
t = tm; /* else repeat assignment over 'tm' */
}
ldebug.luaG_runerror(L, defs.to_luastring("'__newindex' chain too long; possible loop", true));
};
module.exports.cvt2str = cvt2str;
module.exports.cvt2num = cvt2num;
module.exports.luaV_gettable = luaV_gettable;
module.exports.luaV_concat = luaV_concat;
module.exports.luaV_div = luaV_div;
module.exports.luaV_equalobj = luaV_equalobj;
module.exports.luaV_execute = luaV_execute;
module.exports.luaV_finishOp = luaV_finishOp;
module.exports.luaV_lessequal = luaV_lessequal;
module.exports.luaV_lessthan = luaV_lessthan;
module.exports.luaV_mod = luaV_mod;
module.exports.luaV_objlen = luaV_objlen;
module.exports.luaV_rawequalobj = luaV_rawequalobj;
module.exports.luaV_shiftl = luaV_shiftl;
module.exports.luaV_tointeger = luaV_tointeger;
module.exports.settable = settable;
module.exports.tointeger = tointeger;
module.exports.tonumber = tonumber;
/***/ }),
/* 33 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const OpCodes = [
"MOVE",
"LOADK",
"LOADKX",
"LOADBOOL",
"LOADNIL",
"GETUPVAL",
"GETTABUP",
"GETTABLE",
"SETTABUP",
"SETUPVAL",
"SETTABLE",
"NEWTABLE",
"SELF",
"ADD",
"SUB",
"MUL",
"MOD",
"POW",
"DIV",
"IDIV",
"BAND",
"BOR",
"BXOR",
"SHL",
"SHR",
"UNM",
"BNOT",
"NOT",
"LEN",
"CONCAT",
"JMP",
"EQ",
"LT",
"LE",
"TEST",
"TESTSET",
"CALL",
"TAILCALL",
"RETURN",
"FORLOOP",
"FORPREP",
"TFORCALL",
"TFORLOOP",
"SETLIST",
"CLOSURE",
"VARARG",
"EXTRAARG"
];
const OpCodesI = {
OP_MOVE: 0,
OP_LOADK: 1,
OP_LOADKX: 2,
OP_LOADBOOL: 3,
OP_LOADNIL: 4,
OP_GETUPVAL: 5,
OP_GETTABUP: 6,
OP_GETTABLE: 7,
OP_SETTABUP: 8,
OP_SETUPVAL: 9,
OP_SETTABLE: 10,
OP_NEWTABLE: 11,
OP_SELF: 12,
OP_ADD: 13,
OP_SUB: 14,
OP_MUL: 15,
OP_MOD: 16,
OP_POW: 17,
OP_DIV: 18,
OP_IDIV: 19,
OP_BAND: 20,
OP_BOR: 21,
OP_BXOR: 22,
OP_SHL: 23,
OP_SHR: 24,
OP_UNM: 25,
OP_BNOT: 26,
OP_NOT: 27,
OP_LEN: 28,
OP_CONCAT: 29,
OP_JMP: 30,
OP_EQ: 31,
OP_LT: 32,
OP_LE: 33,
OP_TEST: 34,
OP_TESTSET: 35,
OP_CALL: 36,
OP_TAILCALL: 37,
OP_RETURN: 38,
OP_FORLOOP: 39,
OP_FORPREP: 40,
OP_TFORCALL: 41,
OP_TFORLOOP: 42,
OP_SETLIST: 43,
OP_CLOSURE: 44,
OP_VARARG: 45,
OP_EXTRAARG: 46
};
/*
** masks for instruction properties. The format is:
** bits 0-1: op mode
** bits 2-3: C arg mode
** bits 4-5: B arg mode
** bit 6: instruction set register A
** bit 7: operator is a test (next instruction must be a jump)
*/
const OpArgN = 0; /* argument is not used */
const OpArgU = 1; /* argument is used */
const OpArgR = 2; /* argument is a register or a jump offset */
const OpArgK = 3; /* argument is a constant or register/constant */
/* basic instruction format */
const iABC = 0;
const iABx = 1;
const iAsBx = 2;
const iAx = 3;
const luaP_opmodes = [
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iABC, /* OP_MOVE */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgN << 2 | iABx, /* OP_LOADK */
0 << 7 | 1 << 6 | OpArgN << 4 | OpArgN << 2 | iABx, /* OP_LOADKX */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgU << 2 | iABC, /* OP_LOADBOOL */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgN << 2 | iABC, /* OP_LOADNIL */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgN << 2 | iABC, /* OP_GETUPVAL */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgK << 2 | iABC, /* OP_GETTABUP */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgK << 2 | iABC, /* OP_GETTABLE */
0 << 7 | 0 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_SETTABUP */
0 << 7 | 0 << 6 | OpArgU << 4 | OpArgN << 2 | iABC, /* OP_SETUPVAL */
0 << 7 | 0 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_SETTABLE */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgU << 2 | iABC, /* OP_NEWTABLE */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgK << 2 | iABC, /* OP_SELF */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_ADD */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_SUB */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_MUL */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_MOD */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_POW */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_DIV */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_IDIV */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_BAND */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_BOR */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_BXOR */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_SHL */
0 << 7 | 1 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_SHR */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iABC, /* OP_UNM */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iABC, /* OP_BNOT */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iABC, /* OP_NOT */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iABC, /* OP_LEN */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgR << 2 | iABC, /* OP_CONCAT */
0 << 7 | 0 << 6 | OpArgR << 4 | OpArgN << 2 | iAsBx, /* OP_JMP */
1 << 7 | 0 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_EQ */
1 << 7 | 0 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_LT */
1 << 7 | 0 << 6 | OpArgK << 4 | OpArgK << 2 | iABC, /* OP_LE */
1 << 7 | 0 << 6 | OpArgN << 4 | OpArgU << 2 | iABC, /* OP_TEST */
1 << 7 | 1 << 6 | OpArgR << 4 | OpArgU << 2 | iABC, /* OP_TESTSET */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgU << 2 | iABC, /* OP_CALL */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgU << 2 | iABC, /* OP_TAILCALL */
0 << 7 | 0 << 6 | OpArgU << 4 | OpArgN << 2 | iABC, /* OP_RETURN */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iAsBx, /* OP_FORLOOP */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iAsBx, /* OP_FORPREP */
0 << 7 | 0 << 6 | OpArgN << 4 | OpArgU << 2 | iABC, /* OP_TFORCALL */
0 << 7 | 1 << 6 | OpArgR << 4 | OpArgN << 2 | iAsBx, /* OP_TFORLOOP */
0 << 7 | 0 << 6 | OpArgU << 4 | OpArgU << 2 | iABC, /* OP_SETLIST */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgN << 2 | iABx, /* OP_CLOSURE */
0 << 7 | 1 << 6 | OpArgU << 4 | OpArgN << 2 | iABC, /* OP_VARARG */
0 << 7 | 0 << 6 | OpArgU << 4 | OpArgU << 2 | iAx /* OP_EXTRAARG */
];
const getOpMode = function(m) {
return luaP_opmodes[m] & 3;
};
const getBMode = function(m) {
return (luaP_opmodes[m] >> 4) & 3;
};
const getCMode = function(m) {
return (luaP_opmodes[m] >> 2) & 3;
};
const testAMode = function(m) {
return luaP_opmodes[m] & (1 << 6);
};
const testTMode = function(m) {
return luaP_opmodes[m] & (1 << 7);
};
const SIZE_C = 9;
const SIZE_B = 9;
const SIZE_Bx = (SIZE_C + SIZE_B);
const SIZE_A = 8;
const SIZE_Ax = (SIZE_C + SIZE_B + SIZE_A);
const SIZE_OP = 6;
const POS_OP = 0;
const POS_A = (POS_OP + SIZE_OP);
const POS_C = (POS_A + SIZE_A);
const POS_B = (POS_C + SIZE_C);
const POS_Bx = POS_C;
const POS_Ax = POS_A;
const MAXARG_Bx = ((1 << SIZE_Bx) - 1);
const MAXARG_sBx = (MAXARG_Bx >> 1); /* 'sBx' is signed */
const MAXARG_Ax = ((1<<SIZE_Ax)-1);
const MAXARG_A = ((1 << SIZE_A) - 1);
const MAXARG_B = ((1 << SIZE_B) - 1);
const MAXARG_C = ((1 << SIZE_C) - 1);
/* this bit 1 means constant (0 means register) */
const BITRK = (1 << (SIZE_B - 1));
const MAXINDEXRK = (BITRK - 1);
/*
** invalid register that fits in 8 bits
*/
const NO_REG = MAXARG_A;
/* test whether value is a constant */
const ISK = function (x) {
return x & BITRK;
};
/* gets the index of the constant */
const INDEXK = function (r) {
return r & ~BITRK;
};
/* code a constant index as a RK value */
const RKASK = function(x) {
return x | BITRK;
};
/* creates a mask with 'n' 1 bits at position 'p' */
const MASK1 = function(n, p) {
return ((~((~0)<<(n)))<<(p));
};
/* creates a mask with 'n' 0 bits at position 'p' */
const MASK0 = function(n, p) {
return (~MASK1(n, p));
};
const GET_OPCODE = function(i) {
return i.opcode;
};
const SET_OPCODE = function(i, o) {
i.code = (i.code & MASK0(SIZE_OP, POS_OP)) | ((o << POS_OP) & MASK1(SIZE_OP, POS_OP));
return fullins(i);
};
const setarg = function(i, v, pos, size) {
i.code = (i.code & MASK0(size, pos)) | ((v << pos) & MASK1(size, pos));
return fullins(i);
};
const GETARG_A = function(i) {
return i.A;
};
const SETARG_A = function(i,v) {
return setarg(i, v, POS_A, SIZE_A);
};
const GETARG_B = function(i) {
return i.B;
};
const SETARG_B = function(i,v) {
return setarg(i, v, POS_B, SIZE_B);
};
const GETARG_C = function(i) {
return i.C;
};
const SETARG_C = function(i,v) {
return setarg(i, v, POS_C, SIZE_C);
};
const GETARG_Bx = function(i) {
return i.Bx;
};
const SETARG_Bx = function(i,v) {
return setarg(i, v, POS_Bx, SIZE_Bx);
};
const GETARG_Ax = function(i) {
return i.Ax;
};
const SETARG_Ax = function(i,v) {
return setarg(i, v, POS_Ax, SIZE_Ax);
};
const GETARG_sBx = function(i) {
return i.sBx;
};
const SETARG_sBx = function(i, b) {
return SETARG_Bx(i, b + MAXARG_sBx);
};
/*
** Pre-calculate all possible part of the instruction
*/
const fullins = function(ins) {
if (typeof ins === "number") {
return {
code: ins,
opcode: (ins >> POS_OP) & MASK1(SIZE_OP, 0),
A: (ins >> POS_A) & MASK1(SIZE_A, 0),
B: (ins >> POS_B) & MASK1(SIZE_B, 0),
C: (ins >> POS_C) & MASK1(SIZE_C, 0),
Bx: (ins >> POS_Bx) & MASK1(SIZE_Bx, 0),
Ax: (ins >> POS_Ax) & MASK1(SIZE_Ax, 0),
sBx: ((ins >> POS_Bx) & MASK1(SIZE_Bx, 0)) - MAXARG_sBx
};
} else {
let i = ins.code;
ins.opcode = (i >> POS_OP) & MASK1(SIZE_OP, 0);
ins.A = (i >> POS_A) & MASK1(SIZE_A, 0);
ins.B = (i >> POS_B) & MASK1(SIZE_B, 0);
ins.C = (i >> POS_C) & MASK1(SIZE_C, 0);
ins.Bx = (i >> POS_Bx) & MASK1(SIZE_Bx, 0);
ins.Ax = (i >> POS_Ax) & MASK1(SIZE_Ax, 0);
ins.sBx = ((i >> POS_Bx) & MASK1(SIZE_Bx, 0)) - MAXARG_sBx;
return ins;
}
};
const CREATE_ABC = function(o, a, b, c) {
return fullins(o << POS_OP | a << POS_A | b << POS_B | c << POS_C);
};
const CREATE_ABx = function(o, a, bc) {
return fullins(o << POS_OP | a << POS_A | bc << POS_Bx);
};
const CREATE_Ax = function(o, a) {
return fullins(o << POS_OP | a << POS_Ax);
};
/* number of list items to accumulate before a SETLIST instruction */
const LFIELDS_PER_FLUSH = 50;
module.exports.BITRK = BITRK;
module.exports.CREATE_ABC = CREATE_ABC;
module.exports.CREATE_ABx = CREATE_ABx;
module.exports.CREATE_Ax = CREATE_Ax;
module.exports.GET_OPCODE = GET_OPCODE;
module.exports.GETARG_A = GETARG_A;
module.exports.GETARG_B = GETARG_B;
module.exports.GETARG_C = GETARG_C;
module.exports.GETARG_Bx = GETARG_Bx;
module.exports.GETARG_Ax = GETARG_Ax;
module.exports.GETARG_sBx = GETARG_sBx;
module.exports.INDEXK = INDEXK;
module.exports.ISK = ISK;
module.exports.LFIELDS_PER_FLUSH = LFIELDS_PER_FLUSH;
module.exports.MAXARG_A = MAXARG_A;
module.exports.MAXARG_Ax = MAXARG_Ax;
module.exports.MAXARG_B = MAXARG_B;
module.exports.MAXARG_Bx = MAXARG_Bx;
module.exports.MAXARG_C = MAXARG_C;
module.exports.MAXARG_sBx = MAXARG_sBx;
module.exports.MAXINDEXRK = MAXINDEXRK;
module.exports.NO_REG = NO_REG;
module.exports.OpArgK = OpArgK;
module.exports.OpArgN = OpArgN;
module.exports.OpArgR = OpArgR;
module.exports.OpArgU = OpArgU;
module.exports.OpCodes = OpCodes;
module.exports.OpCodesI = OpCodesI;
module.exports.POS_A = POS_A;
module.exports.POS_Ax = POS_Ax;
module.exports.POS_B = POS_B;
module.exports.POS_Bx = POS_Bx;
module.exports.POS_C = POS_C;
module.exports.POS_OP = POS_OP;
module.exports.RKASK = RKASK;
module.exports.SETARG_A = SETARG_A;
module.exports.SETARG_Ax = SETARG_Ax;
module.exports.SETARG_B = SETARG_B;
module.exports.SETARG_Bx = SETARG_Bx;
module.exports.SETARG_C = SETARG_C;
module.exports.SETARG_sBx = SETARG_sBx;
module.exports.SET_OPCODE = SET_OPCODE;
module.exports.SIZE_A = SIZE_A;
module.exports.SIZE_Ax = SIZE_Ax;
module.exports.SIZE_B = SIZE_B;
module.exports.SIZE_Bx = SIZE_Bx;
module.exports.SIZE_C = SIZE_C;
module.exports.SIZE_OP = SIZE_OP;
module.exports.fullins = fullins;
module.exports.getBMode = getBMode;
module.exports.getCMode = getCMode;
module.exports.getOpMode = getOpMode;
module.exports.iABC = iABC;
module.exports.iABx = iABx;
module.exports.iAsBx = iAsBx;
module.exports.iAx = iAx;
module.exports.testAMode = testAMode;
module.exports.testTMode = testTMode;
/***/ }),
/* 34 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* global window, exports, define */
!function() {
'use strict'
var re = {
not_string: /[^s]/,
not_bool: /[^t]/,
not_type: /[^T]/,
not_primitive: /[^v]/,
number: /[diefg]/,
numeric_arg: /[bcdiefguxX]/,
json: /[j]/,
not_json: /[^j]/,
text: /^[^\x25]+/,
modulo: /^\x25{2}/,
placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
key: /^([a-z_][a-z_\d]*)/i,
key_access: /^\.([a-z_][a-z_\d]*)/i,
index_access: /^\[(\d+)\]/,
sign: /^[\+\-]/
}
function sprintf(key) {
// `arguments` is not an array, but should be fine for this call
return sprintf_format(sprintf_parse(key), arguments)
}
function vsprintf(fmt, argv) {
return sprintf.apply(null, [fmt].concat(argv || []))
}
function sprintf_format(parse_tree, argv) {
var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, match, pad, pad_character, pad_length, is_positive, sign
for (i = 0; i < tree_length; i++) {
if (typeof parse_tree[i] === 'string') {
output += parse_tree[i]
}
else if (Array.isArray(parse_tree[i])) {
match = parse_tree[i] // convenience purposes only
if (match[2]) { // keyword argument
arg = argv[cursor]
for (k = 0; k < match[2].length; k++) {
if (!arg.hasOwnProperty(match[2][k])) {
throw new Error(sprintf('[sprintf] property "%s" does not exist', match[2][k]))
}
arg = arg[match[2][k]]
}
}
else if (match[1]) { // positional argument (explicit)
arg = argv[match[1]]
}
else { // positional argument (implicit)
arg = argv[cursor++]
}
if (re.not_type.test(match[8]) && re.not_primitive.test(match[8]) && arg instanceof Function) {
arg = arg()
}
if (re.numeric_arg.test(match[8]) && (typeof arg !== 'number' && isNaN(arg))) {
throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
}
if (re.number.test(match[8])) {
is_positive = arg >= 0
}
switch (match[8]) {
case 'b':
arg = parseInt(arg, 10).toString(2)
break
case 'c':
arg = String.fromCharCode(parseInt(arg, 10))
break
case 'd':
case 'i':
arg = parseInt(arg, 10)
break
case 'j':
arg = JSON.stringify(arg, null, match[6] ? parseInt(match[6]) : 0)
break
case 'e':
arg = match[7] ? parseFloat(arg).toExponential(match[7]) : parseFloat(arg).toExponential()
break
case 'f':
arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg)
break
case 'g':
arg = match[7] ? String(Number(arg.toPrecision(match[7]))) : parseFloat(arg)
break
case 'o':
arg = (parseInt(arg, 10) >>> 0).toString(8)
break
case 's':
arg = String(arg)
arg = (match[7] ? arg.substring(0, match[7]) : arg)
break
case 't':
arg = String(!!arg)
arg = (match[7] ? arg.substring(0, match[7]) : arg)
break
case 'T':
arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
arg = (match[7] ? arg.substring(0, match[7]) : arg)
break
case 'u':
arg = parseInt(arg, 10) >>> 0
break
case 'v':
arg = arg.valueOf()
arg = (match[7] ? arg.substring(0, match[7]) : arg)
break
case 'x':
arg = (parseInt(arg, 10) >>> 0).toString(16)
break
case 'X':
arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
break
}
if (re.json.test(match[8])) {
output += arg
}
else {
if (re.number.test(match[8]) && (!is_positive || match[3])) {
sign = is_positive ? '+' : '-'
arg = arg.toString().replace(re.sign, '')
}
else {
sign = ''
}
pad_character = match[4] ? match[4] === '0' ? '0' : match[4].charAt(1) : ' '
pad_length = match[6] - (sign + arg).length
pad = match[6] ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
output += match[5] ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
}
}
}
return output
}
var sprintf_cache = Object.create(null)
function sprintf_parse(fmt) {
if (sprintf_cache[fmt]) {
return sprintf_cache[fmt]
}
var _fmt = fmt, match, parse_tree = [], arg_names = 0
while (_fmt) {
if ((match = re.text.exec(_fmt)) !== null) {
parse_tree.push(match[0])
}
else if ((match = re.modulo.exec(_fmt)) !== null) {
parse_tree.push('%')
}
else if ((match = re.placeholder.exec(_fmt)) !== null) {
if (match[2]) {
arg_names |= 1
var field_list = [], replacement_field = match[2], field_match = []
if ((field_match = re.key.exec(replacement_field)) !== null) {
field_list.push(field_match[1])
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
if ((field_match = re.key_access.exec(replacement_field)) !== null) {
field_list.push(field_match[1])
}
else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
field_list.push(field_match[1])
}
else {
throw new SyntaxError('[sprintf] failed to parse named argument key')
}
}
}
else {
throw new SyntaxError('[sprintf] failed to parse named argument key')
}
match[2] = field_list
}
else {
arg_names |= 2
}
if (arg_names === 3) {
throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
}
parse_tree.push(match)
}
else {
throw new SyntaxError('[sprintf] unexpected placeholder')
}
_fmt = _fmt.substring(match[0].length)
}
return sprintf_cache[fmt] = parse_tree
}
/**
* export to either browser or node.js
*/
/* eslint-disable quote-props */
if (true) {
exports['sprintf'] = sprintf
exports['vsprintf'] = vsprintf
}
if (typeof window !== 'undefined') {
window['sprintf'] = sprintf
window['vsprintf'] = vsprintf
if (true) {
!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
return {
'sprintf': sprintf,
'vsprintf': vsprintf
}
}.call(exports, __webpack_require__, exports, module),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))
}
}
/* eslint-enable quote-props */
}()
/***/ }),
/* 35 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
class MBuffer {
constructor() {
this.buffer = null;
this.n = 0;
}
}
const luaZ_buffremove = function(buff, i) {
buff.n -= i;
};
const luaZ_resetbuffer = function(buff) {
buff.n = 0;
buff.buffer = [];
};
class ZIO {
constructor(L, reader, data) {
this.L = L; /* Lua state (for reader) */
assert(typeof reader == "function", "ZIO requires a reader");
this.reader = reader; /* reader function */
this.data = data; /* additional data */
this.n = 0; /* bytes still unread */
this.buffer = null;
this.off = 0; /* current position in buffer */
}
zgetc () {
return ((this.n--) > 0) ? this.buffer[this.off++] : luaZ_fill(this);
}
}
const EOZ = -1;
const luaZ_fill = function(z) {
let size;
let buff = z.reader(z.L, z.data);
if (buff === null)
return EOZ;
if (buff instanceof DataView) {
z.buffer = new Uint8Array(buff.buffer, buff.byteOffset, buff.byteLength);
z.off = 0;
size = buff.byteLength - buff.byteOffset;
} else {
assert(typeof buff !== "string", "Should only load binary of array of bytes");
z.buffer = buff;
z.off = 0;
size = buff.length;
}
if (size === 0)
return EOZ;
z.n = size - 1;
return z.buffer[z.off++];
};
/* b should be an array-like that will be set to bytes
* b_offset is the offset at which to start filling */
const luaZ_read = function(z, b, b_offset, n) {
while (n) {
if (z.n === 0) { /* no bytes in buffer? */
if (luaZ_fill(z) === EOZ)
return n; /* no more input; return number of missing bytes */
else {
z.n++; /* luaZ_fill consumed first byte; put it back */
z.off--;
}
}
let m = (n <= z.n) ? n : z.n; /* min. between n and z->n */
for (let i=0; i<m; i++) {
b[b_offset++] = z.buffer[z.off++];
}
z.n -= m;
if (z.n === 0) // remove reference to input so it can get freed
z.buffer = null;
n -= m;
}
return 0;
};
module.exports.EOZ = EOZ;
module.exports.luaZ_buffremove = luaZ_buffremove;
module.exports.luaZ_fill = luaZ_fill;
module.exports.luaZ_read = luaZ_read;
module.exports.luaZ_resetbuffer = luaZ_resetbuffer;
module.exports.MBuffer = MBuffer;
module.exports.ZIO = ZIO;
/***/ }),
/* 36 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
class MBuffer {
constructor() {
this.buffer = null;
this.n = 0;
}
}
const luaZ_buffremove = function(buff, i) {
buff.n -= i;
};
const luaZ_resetbuffer = function(buff) {
buff.n = 0;
buff.buffer = [];
};
class ZIO {
constructor(L, reader, data) {
this.L = L; /* Lua state (for reader) */
assert(typeof reader == "function", "ZIO requires a reader");
this.reader = reader; /* reader function */
this.data = data; /* additional data */
this.n = 0; /* bytes still unread */
this.buffer = null;
this.off = 0; /* current position in buffer */
}
zgetc () {
return ((this.n--) > 0) ? this.buffer[this.off++] : luaZ_fill(this);
}
}
const EOZ = -1;
const luaZ_fill = function(z) {
let size;
let buff = z.reader(z.L, z.data);
if (buff === null)
return EOZ;
if (buff instanceof DataView) {
z.buffer = new Uint8Array(buff.buffer, buff.byteOffset, buff.byteLength);
z.off = 0;
size = buff.byteLength - buff.byteOffset;
} else {
assert(typeof buff !== "string", "Should only load binary of array of bytes");
z.buffer = buff;
z.off = 0;
size = buff.length;
}
if (size === 0)
return EOZ;
z.n = size - 1;
return z.buffer[z.off++];
};
/* b should be an array-like that will be set to bytes
* b_offset is the offset at which to start filling */
const luaZ_read = function(z, b, b_offset, n) {
while (n) {
if (z.n === 0) { /* no bytes in buffer? */
if (luaZ_fill(z) === EOZ)
return n; /* no more input; return number of missing bytes */
else {
z.n++; /* luaZ_fill consumed first byte; put it back */
z.off--;
}
}
let m = (n <= z.n) ? n : z.n; /* min. between n and z->n */
for (let i=0; i<m; i++) {
b[b_offset++] = z.buffer[z.off++];
}
z.n -= m;
if (z.n === 0) // remove reference to input so it can get freed
z.buffer = null;
n -= m;
}
return 0;
};
module.exports.EOZ = EOZ;
module.exports.luaZ_buffremove = luaZ_buffremove;
module.exports.luaZ_fill = luaZ_fill;
module.exports.luaZ_read = luaZ_read;
module.exports.luaZ_resetbuffer = luaZ_resetbuffer;
module.exports.MBuffer = MBuffer;
module.exports.ZIO = ZIO;
/***/ }),
/* 37 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const ldebug = __webpack_require__(19);
const ldo = __webpack_require__(12);
const ldump = __webpack_require__(72);
const lfunc = __webpack_require__(20);
const lobject = __webpack_require__(5);
const lstate = __webpack_require__(21);
const lstring = __webpack_require__(15);
const ltm = __webpack_require__(26);
const luaconf = __webpack_require__(18);
const lvm = __webpack_require__(27);
const ltable = __webpack_require__(14);
const lzio = __webpack_require__(35);
const MAXUPVAL = lfunc.MAXUPVAL;
const CT = defs.constant_types;
const TS = defs.thread_status;
const TValue = lobject.TValue;
const CClosure = lobject.CClosure;
const isvalid = function(o) {
return o !== lobject.luaO_nilobject;
};
const lua_version = function(L) {
if (L === null) return defs.LUA_VERSION_NUM;
else return L.l_G.version;
};
const lua_atpanic = function(L, panicf) {
let old = L.l_G.panic;
L.l_G.panic = panicf;
return old;
};
const lua_atnativeerror = function(L, errorf) {
let old = L.l_G.atnativeerror;
L.l_G.atnativeerror = errorf;
return old;
};
// Return value for idx on stack
const index2addr = function(L, idx) {
let ci = L.ci;
if (idx > 0) {
let o = ci.funcOff + idx;
assert(idx <= ci.top - (ci.funcOff + 1), "unacceptable index");
if (o >= L.top) return lobject.luaO_nilobject;
else return L.stack[o];
} else if (idx > defs.LUA_REGISTRYINDEX) {
assert(idx !== 0 && -idx <= L.top, "invalid index");
return L.stack[L.top + idx];
} else if (idx === defs.LUA_REGISTRYINDEX) {
return L.l_G.l_registry;
} else { /* upvalues */
idx = defs.LUA_REGISTRYINDEX - idx;
assert(idx <= MAXUPVAL + 1, "upvalue index too large");
if (ci.func.ttislcf()) /* light C function? */
return lobject.luaO_nilobject; /* it has no upvalues */
else {
return idx <= ci.func.value.nupvalues ? ci.func.value.upvalue[idx - 1] : lobject.luaO_nilobject;
}
}
};
// Like index2addr but returns the index on stack; doesn't allow pseudo indices
const index2addr_ = function(L, idx) {
let ci = L.ci;
if (idx > 0) {
let o = ci.funcOff + idx;
assert(idx <= ci.top - (ci.funcOff + 1), "unacceptable index");
if (o >= L.top) return null;
else return o;
} else if (idx > defs.LUA_REGISTRYINDEX) {
assert(idx !== 0 && -idx <= L.top, "invalid index");
return L.top + idx;
} else { /* registry or upvalue */
throw Error("attempt to use pseudo-index");
}
};
const lua_checkstack = function(L, n) {
let res;
let ci = L.ci;
assert(n >= 0, "negative 'n'");
if (L.stack_last - L.top > n) /* stack large enough? */
res = true;
else { /* no; need to grow stack */
let inuse = L.top + lstate.EXTRA_STACK;
if (inuse > luaconf.LUAI_MAXSTACK - n) /* can grow without overflow? */
res = false; /* no */
else { /* try to grow stack */
ldo.luaD_growstack(L, n);
res = true;
}
}
if (res && ci.top < L.top + n)
ci.top = L.top + n; /* adjust frame top */
return res;
};
const lua_xmove = function(from, to, n) {
if (from === to) return;
assert(n < (from.top - from.ci.funcOff), "not enough elements in the stack");
assert(from.l_G === to.l_G, "moving among independent states");
assert(to.ci.top - to.top >= n, "stack overflow");
from.top -= n;
for (let i = 0; i < n; i++) {
to.stack[to.top] = new lobject.TValue();
lobject.setobj2s(to, to.top, from.stack[from.top + i]);
delete from.stack[from.top + i];
to.top++;
}
};
/*
** basic stack manipulation
*/
/*
** convert an acceptable stack index into an absolute index
*/
const lua_absindex = function(L, idx) {
return (idx > 0 || idx <= defs.LUA_REGISTRYINDEX)
? idx
: (L.top - L.ci.funcOff) + idx;
};
const lua_gettop = function(L) {
return L.top - (L.ci.funcOff + 1);
};
const lua_pushvalue = function(L, idx) {
lobject.pushobj2s(L, index2addr(L, idx));
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_settop = function(L, idx) {
let func = L.ci.funcOff;
let newtop;
if (idx >= 0) {
assert(idx <= L.stack_last - (func + 1), "new top too large");
newtop = func + 1 + idx;
} else {
assert(-(idx + 1) <= L.top - (func + 1), "invalid new top");
newtop = L.top + idx + 1; /* 'subtract' index (index is negative) */
}
ldo.adjust_top(L, newtop);
};
const lua_pop = function(L, n) {
lua_settop(L, -n - 1);
};
const reverse = function(L, from, to) {
for (; from < to; from++, to--) {
let fromtv = L.stack[from];
let temp = new TValue(fromtv.type, fromtv.value);
lobject.setobjs2s(L, from, to);
lobject.setobj2s(L, to, temp);
}
};
/*
** Let x = AB, where A is a prefix of length 'n'. Then,
** rotate x n === BA. But BA === (A^r . B^r)^r.
*/
const lua_rotate = function(L, idx, n) {
let t = L.top - 1;
let pIdx = index2addr_(L, idx);
let p = L.stack[pIdx];
assert(isvalid(p) && idx > defs.LUA_REGISTRYINDEX, "index not in the stack");
assert((n >= 0 ? n : -n) <= (t - pIdx + 1), "invalid 'n'");
let m = n >= 0 ? t - n : pIdx - n - 1; /* end of prefix */
reverse(L, pIdx, m);
reverse(L, m + 1, L.top - 1);
reverse(L, pIdx, L.top - 1);
};
const lua_copy = function(L, fromidx, toidx) {
let from = index2addr(L, fromidx);
index2addr(L, toidx).setfrom(from);
};
const lua_remove = function(L, idx) {
lua_rotate(L, idx, -1);
lua_pop(L, 1);
};
const lua_insert = function(L, idx) {
lua_rotate(L, idx, 1);
};
const lua_replace = function(L, idx) {
lua_copy(L, -1, idx);
lua_pop(L, 1);
};
/*
** push functions (JS -> stack)
*/
const lua_pushnil = function(L) {
L.stack[L.top] = new TValue(CT.LUA_TNIL, null);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushnumber = function(L, n) {
assert(typeof n === "number");
L.stack[L.top] = new TValue(CT.LUA_TNUMFLT, n);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushinteger = function(L, n) {
assert(typeof n === "number" && (n|0) === n);
L.stack[L.top] = new TValue(CT.LUA_TNUMINT, n);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushlstring = function(L, s, len) {
assert(typeof len === "number");
let ts;
if (len === 0) {
ts = lstring.luaS_bless(L, []);
} else {
assert(defs.is_luastring(s) && s.length >= len, "lua_pushlstring expects array of byte");
ts = lstring.luaS_bless(L, s.slice(0, len));
}
lobject.pushsvalue2s(L, ts);
assert(L.top <= L.ci.top, "stack overflow");
return ts.value;
};
const lua_pushstring = function (L, s) {
assert(defs.is_luastring(s) || s === undefined || s === null, "lua_pushstring expects array of byte");
if (s === undefined || s === null) {
L.stack[L.top] = new TValue(CT.LUA_TNIL, null);
L.top++;
} else {
let ts = lstring.luaS_new(L, s);
lobject.pushsvalue2s(L, ts);
s = ts.getstr(); /* internal copy */
}
assert(L.top <= L.ci.top, "stack overflow");
return s;
};
const lua_pushvfstring = function (L, fmt, argp) {
assert(defs.is_luastring(fmt));
return lobject.luaO_pushvfstring(L, fmt, argp);
};
const lua_pushfstring = function (L, fmt, ...argp) {
assert(defs.is_luastring(fmt));
return lobject.luaO_pushvfstring(L, fmt, argp);
};
/* Similar to lua_pushstring, but takes a JS string */
const lua_pushliteral = function (L, s) {
assert(typeof s === "string" || s === undefined || s === null, "lua_pushliteral expects a JS string");
if (s === undefined || s === null) {
L.stack[L.top] = new TValue(CT.LUA_TNIL, null);
L.top++;
} else {
let ts = lstring.luaS_newliteral(L, s);
lobject.pushsvalue2s(L, ts);
s = ts.getstr(); /* internal copy */
}
assert(L.top <= L.ci.top, "stack overflow");
return s;
};
const lua_pushcclosure = function(L, fn, n) {
assert(typeof fn === "function");
assert(typeof n === "number");
if (n === 0)
L.stack[L.top] = new TValue(CT.LUA_TLCF, fn);
else {
assert(n < L.top - L.ci.funcOff, "not enough elements in the stack");
assert(n <= MAXUPVAL, "upvalue index too large");
let cl = new CClosure(L, fn, n);
for (let i=0; i<n; i++)
cl.upvalue[i].setfrom(L.stack[L.top - n + i]);
for (let i=1; i<n; i++)
delete L.stack[--L.top];
if (n>0)
--L.top;
L.stack[L.top].setclCvalue(cl);
}
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushjsclosure = lua_pushcclosure;
const lua_pushcfunction = function(L, fn) {
lua_pushcclosure(L, fn, 0);
};
const lua_pushjsfunction = lua_pushcfunction;
const lua_pushboolean = function(L, b) {
L.stack[L.top] = new TValue(CT.LUA_TBOOLEAN, b ? true : false);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushlightuserdata = function(L, p) {
L.stack[L.top] = new TValue(CT.LUA_TLIGHTUSERDATA, p);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushthread = function(L) {
L.stack[L.top] = new TValue(CT.LUA_TTHREAD, L);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
return L.l_G.mainthread === L;
};
const lua_pushglobaltable = function(L) {
lua_rawgeti(L, defs.LUA_REGISTRYINDEX, defs.LUA_RIDX_GLOBALS);
};
/*
** set functions (stack -> Lua)
*/
/*
** t[k] = value at the top of the stack (where 'k' is a string)
*/
const auxsetstr = function(L, t, k) {
assert(defs.is_luastring(k), "key must be an array of bytes");
let str = lstring.luaS_new(L, k);
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
lobject.pushsvalue2s(L, str); /* push 'str' (to make it a TValue) */
assert(L.top <= L.ci.top, "stack overflow");
lvm.settable(L, t, L.stack[L.top - 1], L.stack[L.top - 2]);
/* pop value and key */
delete L.stack[--L.top];
delete L.stack[--L.top];
};
const lua_setglobal = function(L, name) {
auxsetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, defs.LUA_RIDX_GLOBALS), name);
};
const lua_setmetatable = function(L, objindex) {
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let mt;
let obj = index2addr(L, objindex);
if (L.stack[L.top - 1].ttisnil())
mt = null;
else {
assert(L.stack[L.top - 1].ttistable(), "table expected");
mt = L.stack[L.top - 1].value;
}
switch (obj.ttnov()) {
case CT.LUA_TUSERDATA:
case CT.LUA_TTABLE: {
obj.value.metatable = mt;
break;
}
default: {
L.l_G.mt[obj.ttnov()] = mt;
break;
}
}
delete L.stack[--L.top];
return true;
};
const lua_settable = function(L, idx) {
assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack");
let t = index2addr(L, idx);
lvm.settable(L, t, L.stack[L.top - 2], L.stack[L.top - 1]);
delete L.stack[--L.top];
delete L.stack[--L.top];
};
const lua_setfield = function(L, idx, k) {
auxsetstr(L, index2addr(L, idx), k);
};
const lua_seti = function(L, idx, n) {
assert(typeof n === "number" && (n|0) === n);
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let t = index2addr(L, idx);
L.stack[L.top] = new TValue(CT.LUA_TNUMINT, n);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
lvm.settable(L, t, L.stack[L.top - 1], L.stack[L.top - 2]);
/* pop value and key */
delete L.stack[--L.top];
delete L.stack[--L.top];
};
const lua_rawset = function(L, idx) {
assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack");
let o = index2addr(L, idx);
assert(o.ttistable(), "table expected");
let k = L.stack[L.top - 2];
let v = L.stack[L.top - 1];
if (v.ttisnil()) {
ltable.luaH_delete(L, o.value, k);
} else {
let slot = ltable.luaH_set(L, o.value, k);
slot.setfrom(v);
}
ltable.invalidateTMcache(o.value);
delete L.stack[--L.top];
delete L.stack[--L.top];
};
const lua_rawseti = function(L, idx, n) {
assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack");
let o = index2addr(L, idx);
assert(o.ttistable(), "table expected");
ltable.luaH_setint(o.value, n, L.stack[L.top - 1]);
delete L.stack[--L.top];
};
const lua_rawsetp = function(L, idx, p) {
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let o = index2addr(L, idx);
assert(L, o.ttistable(), "table expected");
let k = new TValue(CT.LUA_TLIGHTUSERDATA, p);
let v = L.stack[L.top - 1];
if (v.ttisnil()) {
ltable.luaH_delete(L, o.value, k);
} else {
let slot = ltable.luaH_set(L, o.value, k);
slot.setfrom(v);
}
delete L.stack[--L.top];
};
/*
** get functions (Lua -> stack)
*/
const auxgetstr = function(L, t, k) {
assert(defs.is_luastring(k), "key must be an array of bytes");
let str = lstring.luaS_new(L, k);
lobject.pushsvalue2s(L, str);
assert(L.top <= L.ci.top, "stack overflow");
lvm.luaV_gettable(L, t, L.stack[L.top - 1], L.top - 1);
return L.stack[L.top - 1].ttnov();
};
const lua_rawgeti = function(L, idx, n) {
let t = index2addr(L, idx);
assert(t.ttistable(), "table expected");
lobject.pushobj2s(L, ltable.luaH_getint(t.value, n));
assert(L.top <= L.ci.top, "stack overflow");
return L.stack[L.top - 1].ttnov();
};
const lua_rawgetp = function(L, idx, p) {
let t = index2addr(L, idx);
assert(t.ttistable(), "table expected");
let k = new TValue(CT.LUA_TLIGHTUSERDATA, p);
lobject.pushobj2s(L, ltable.luaH_get(L, t.value, k));
assert(L.top <= L.ci.top, "stack overflow");
return L.stack[L.top - 1].ttnov();
};
const lua_rawget = function(L, idx) {
let t = index2addr(L, idx);
assert(t.ttistable(t), "table expected");
lobject.setobj2s(L, L.top - 1, ltable.luaH_get(L, t.value, L.stack[L.top - 1]));
return L.stack[L.top - 1].ttnov();
};
// narray and nrec are mostly useless for this implementation
const lua_createtable = function(L, narray, nrec) {
let t = new lobject.TValue(CT.LUA_TTABLE, ltable.luaH_new(L));
L.stack[L.top] = t;
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const luaS_newudata = function(L, size) {
return new lobject.Udata(L, size);
};
const lua_newuserdata = function(L, size) {
let u = luaS_newudata(L, size);
L.stack[L.top] = new lobject.TValue(CT.LUA_TUSERDATA, u);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
return u.data;
};
const aux_upvalue = function(L, fi, n) {
switch(fi.ttype()) {
case CT.LUA_TCCL: { /* C closure */
let f = fi.value;
if (!(1 <= n && n <= f.nupvalues)) return null;
return {
name: [],
val: f.upvalue[n-1]
};
}
case CT.LUA_TLCL: { /* Lua closure */
let f = fi.value;
let p = f.p;
if (!(1 <= n && n <= p.upvalues.length)) return null;
let name = p.upvalues[n-1].name;
return {
name: name ? name.getstr() : defs.to_luastring("(*no name)", true),
val: f.upvals[n-1].v
};
}
default: return null; /* not a closure */
}
};
const lua_getupvalue = function(L, funcindex, n) {
let up = aux_upvalue(L, index2addr(L, funcindex), n);
if (up) {
let name = up.name;
let val = up.val;
lobject.pushobj2s(L, val);
assert(L.top <= L.ci.top, "stack overflow");
return name;
}
return null;
};
const lua_setupvalue = function(L, funcindex, n) {
let fi = index2addr(L, funcindex);
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let aux = aux_upvalue(L, fi, n);
if (aux) {
let name = aux.name;
let val = aux.val;
val.setfrom(L.stack[L.top-1]);
delete L.stack[--L.top];
return name;
}
return null;
};
const lua_newtable = function(L) {
lua_createtable(L, 0, 0);
};
const lua_register = function(L, n, f) {
lua_pushcfunction(L, f);
lua_setglobal(L, n);
};
const lua_getmetatable = function(L, objindex) {
let obj = index2addr(L, objindex);
let mt;
let res = false;
switch (obj.ttnov()) {
case CT.LUA_TTABLE:
case CT.LUA_TUSERDATA:
mt = obj.value.metatable;
break;
default:
mt = L.l_G.mt[obj.ttnov()];
break;
}
if (mt !== null && mt !== undefined) {
L.stack[L.top] = new TValue(CT.LUA_TTABLE, mt);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
res = true;
}
return res;
};
const lua_getuservalue = function(L, idx) {
let o = index2addr(L, idx);
assert(L, o.ttisfulluserdata(), "full userdata expected");
let uv = o.value.uservalue;
L.stack[L.top] = new TValue(uv.type, uv.value);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
return L.stack[L.top - 1].ttnov();
};
const lua_gettable = function(L, idx) {
let t = index2addr(L, idx);
lvm.luaV_gettable(L, t, L.stack[L.top - 1], L.top - 1);
return L.stack[L.top - 1].ttnov();
};
const lua_getfield = function(L, idx, k) {
return auxgetstr(L, index2addr(L, idx), k);
};
const lua_geti = function(L, idx, n) {
assert(typeof n === "number" && (n|0) === n);
let t = index2addr(L, idx);
L.stack[L.top] = new TValue(CT.LUA_TNUMINT, n);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
lvm.luaV_gettable(L, t, L.stack[L.top - 1], L.top - 1);
return L.stack[L.top - 1].ttnov();
};
const lua_getglobal = function(L, name) {
return auxgetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, defs.LUA_RIDX_GLOBALS), name);
};
/*
** access functions (stack -> JS)
*/
const lua_toboolean = function(L, idx) {
let o = index2addr(L, idx);
return !o.l_isfalse();
};
const lua_tolstring = function(L, idx) {
let o = index2addr(L, idx);
if (!o.ttisstring()) {
if (!lvm.cvt2str(o)) { /* not convertible? */
return null;
}
lobject.luaO_tostring(L, o);
}
return o.svalue();
};
const lua_tostring = lua_tolstring;
const lua_toljsstring = function(L, idx) {
let o = index2addr(L, idx);
if (!o.ttisstring()) {
if (!lvm.cvt2str(o)) { /* not convertible? */
return null;
}
lobject.luaO_tostring(L, o);
}
return o.jsstring();
};
const lua_tojsstring = lua_toljsstring;
const lua_todataview = function(L, idx) {
let o = index2addr(L, idx);
if (!o.ttisstring()) {
if (!lvm.cvt2str(o)) { /* not convertible? */
return null;
}
lobject.luaO_tostring(L, o);
}
let dv = new DataView(new ArrayBuffer(o.vslen()));
o.svalue().forEach((e, i) => dv.setUint8(i, e, true));
return dv;
};
const lua_rawlen = function(L, idx) {
let o = index2addr(L, idx);
switch (o.ttype()) {
case CT.LUA_TSHRSTR:
case CT.LUA_TLNGSTR:
return o.vslen();
case CT.LUA_TUSERDATA:
return o.value.len;
case CT.LUA_TTABLE:
return ltable.luaH_getn(o.value);
default:
return 0;
}
};
const lua_tocfunction = function(L, idx) {
let o = index2addr(L, idx);
if (o.ttislcf() || o.ttisCclosure()) return o.value;
else return null; /* not a C function */
};
const lua_tointeger = function(L, idx) {
return lvm.tointeger(index2addr(L, idx));
};
const lua_tonumber = function(L, idx) {
let n = lvm.tonumber(index2addr(L, idx));
return n === false ? 0 : n;
};
const lua_tonumberx = function(L, idx) {
return lvm.tonumber(index2addr(L, idx));
};
const lua_touserdata = function(L, idx) {
let o = index2addr(L, idx);
switch (o.ttnov()) {
case CT.LUA_TUSERDATA:
return o.value.data;
case CT.LUA_TLIGHTUSERDATA:
return o.value;
default: return null;
}
};
const lua_tothread = function(L, idx) {
let o = index2addr(L, idx);
return o.ttisthread() ? o.value : null;
};
const lua_topointer = function(L, idx) {
let o = index2addr(L, idx);
switch (o.ttype()) {
case CT.LUA_TTABLE:
case CT.LUA_TLCL:
case CT.LUA_TCCL:
case CT.LUA_TLCF:
case CT.LUA_TTHREAD:
case CT.LUA_TUSERDATA: /* note: this differs in behaviour to reference lua implementation */
case CT.LUA_TLIGHTUSERDATA:
return o.value;
default:
return null;
}
};
/* A proxy is a function that the same lua value to the given lua state. */
/* Having a weakmap of created proxies was only way I could think of to provide an 'isproxy' function */
const seen = new WeakMap();
/* is the passed object a proxy? is it from the given state? (if passed) */
const lua_isproxy = function(p, L) {
let G = seen.get(p);
if (!G)
return false;
return (L === null) || (L.l_G === G);
};
/* Use 'create_proxy' helper function so that 'L' is not in scope */
const create_proxy = function(G, type, value) {
let proxy = function(L) {
assert(L instanceof lstate.lua_State && G === L.l_G, "must be from same global state");
L.stack[L.top] = new TValue(type, value);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
seen.set(proxy, G);
return proxy;
};
const lua_toproxy = function(L, idx) {
let tv = index2addr(L, idx);
/* pass broken down tv incase it is an upvalue index */
return create_proxy(L.l_G, tv.type, tv.value);
};
const lua_compare = function(L, index1, index2, op) {
let o1 = index2addr(L, index1);
let o2 = index2addr(L, index2);
let i = 0;
if (isvalid(o1) && isvalid(o2)) {
switch (op) {
case defs.LUA_OPEQ: i = lvm.luaV_equalobj(L, o1, o2); break;
case defs.LUA_OPLT: i = lvm.luaV_lessthan(L, o1, o2); break;
case defs.LUA_OPLE: i = lvm.luaV_lessequal(L, o1, o2); break;
default: assert(false, "invalid option");
}
}
return i;
};
const lua_stringtonumber = function(L, s) {
let tv = lobject.luaO_str2num(s);
if (tv) {
L.stack[L.top] = tv;
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
return s.length+1;
}
return 0;
};
const lua_tointegerx = function(L, idx) {
return lvm.tointeger(index2addr(L, idx));
};
const f_call = function(L, ud) {
ldo.luaD_callnoyield(L, ud.funcOff, ud.nresults);
};
const lua_type = function(L, idx) {
let o = index2addr(L, idx);
return isvalid(o) ? o.ttnov() : CT.LUA_TNONE;
};
const lua_typename = function(L, t) {
assert(CT.LUA_TNONE <= t && t < CT.LUA_NUMTAGS, "invalid tag");
return ltm.ttypename(t);
};
const lua_iscfunction = function(L, idx) {
let o = index2addr(L, idx);
return o.ttislcf(o) || o.ttisCclosure();
};
const lua_isnil = function(L, n) {
return lua_type(L, n) === CT.LUA_TNIL;
};
const lua_isboolean = function(L, n) {
return lua_type(L, n) === CT.LUA_TBOOLEAN;
};
const lua_isnone = function(L, n) {
return lua_type(L, n) === CT.LUA_TNONE;
};
const lua_isnoneornil = function(L, n) {
return lua_type(L, n) <= 0;
};
const lua_istable = function(L, idx) {
return index2addr(L, idx).ttistable();
};
const lua_isinteger = function(L, idx) {
return index2addr(L, idx).ttisinteger();
};
const lua_isnumber = function(L, idx) {
return lvm.tonumber(index2addr(L, idx)) !== false;
};
const lua_isstring = function(L, idx) {
let o = index2addr(L, idx);
return o.ttisstring() || lvm.cvt2str(o);
};
const lua_isuserdata = function(L, idx) {
let o = index2addr(L, idx);
return o.ttisfulluserdata(o) || o.ttislightuserdata();
};
const lua_isthread = function(L, idx) {
return lua_type(L, idx) === CT.LUA_TTHREAD;
};
const lua_isfunction = function(L, idx) {
return lua_type(L, idx) === CT.LUA_TFUNCTION;
};
const lua_islightuserdata = function(L, idx) {
return lua_type(L, idx) === CT.LUA_TLIGHTUSERDATA;
};
const lua_rawequal = function(L, index1, index2) {
let o1 = index2addr(L, index1);
let o2 = index2addr(L, index2);
return isvalid(o1) && isvalid(o2) ? lvm.luaV_equalobj(null, o1, o2) : 0; // TODO: isvalid ?
};
const lua_arith = function(L, op) {
if (op !== defs.LUA_OPUNM && op !== defs.LUA_OPBNOT)
assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack"); /* all other operations expect two operands */
else { /* for unary operations, add fake 2nd operand */
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
lobject.pushobj2s(L, L.stack[L.top-1]);
assert(L.top <= L.ci.top, "stack overflow");
}
/* first operand at top - 2, second at top - 1; result go to top - 2 */
lobject.luaO_arith(L, op, L.stack[L.top - 2], L.stack[L.top - 1], L.stack[L.top - 2]);
delete L.stack[--L.top]; /* remove second operand */
};
/*
** 'load' and 'call' functions (run Lua code)
*/
const lua_load = function(L, reader, data, chunkname, mode) {
assert(defs.is_luastring(chunkname), "lua_load expect an array of byte as chunkname");
assert(mode ? defs.is_luastring(mode) : true, "lua_load expect an array of byte as mode");
if (!chunkname) chunkname = [defs.char["?"]];
let z = new lzio.ZIO(L, reader, data);
let status = ldo.luaD_protectedparser(L, z, chunkname, mode);
if (status === TS.LUA_OK) { /* no errors? */
let f = L.stack[L.top - 1].value; /* get newly created function */
if (f.nupvalues >= 1) { /* does it have an upvalue? */
/* get global table from registry */
let gt = ltable.luaH_getint(L.l_G.l_registry.value, defs.LUA_RIDX_GLOBALS);
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
f.upvals[0].v.setfrom(gt);
}
}
return status;
};
const lua_dump = function(L, writer, data, strip) {
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let o = L.stack[L.top -1];
if (o.ttisLclosure())
return ldump.luaU_dump(L, o.value.p, writer, data, strip);
return 1;
};
const lua_status = function(L) {
return L.status;
};
const lua_setuservalue = function(L, idx) {
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let o = index2addr(L, idx);
assert(L, o.ttisfulluserdata(), "full userdata expected");
o.value.uservalue.setfrom(L.stack[L.top - 1]);
delete L.stack[--L.top];
};
const lua_callk = function(L, nargs, nresults, ctx, k) {
assert(k === null || !(L.ci.callstatus & lstate.CIST_LUA), "cannot use continuations inside hooks");
assert(nargs + 1 < L.top - L.ci.funcOff, "not enough elements in the stack");
assert(L.status === TS.LUA_OK, "cannot do calls on non-normal thread");
assert(nargs === defs.LUA_MULTRET || (L.ci.top - L.top >= nargs - nresults), "results from function overflow current stack size");
let func = L.top - (nargs + 1);
if (k !== null && L.nny === 0) { /* need to prepare continuation? */
L.ci.c_k = k;
L.ci.c_ctx = ctx;
ldo.luaD_call(L, func, nresults);
} else { /* no continuation or no yieldable */
ldo.luaD_callnoyield(L, func, nresults);
}
if (nresults === defs.LUA_MULTRET && L.ci.top < L.top)
L.ci.top = L.top;
};
const lua_call = function(L, n, r) {
lua_callk(L, n, r, 0, null);
};
const lua_pcallk = function(L, nargs, nresults, errfunc, ctx, k) {
assert(nargs + 1 < L.top - L.ci.funcOff, "not enough elements in the stack");
assert(L.status === TS.LUA_OK, "cannot do calls on non-normal thread");
assert(nargs === defs.LUA_MULTRET || (L.ci.top - L.top >= nargs - nresults), "results from function overflow current stack size");
let c = {
func: null,
funcOff: NaN,
nresults: NaN
};
let status;
let func;
if (errfunc === 0)
func = 0;
else {
// let o = index2addr(L, errfunc);
// TODO: api_checkstackindex(L, errfunc, o);
func = index2addr_(L, errfunc);
}
c.funcOff = L.top - (nargs + 1); /* function to be called */
c.func = L.stack[c.funcOff];
if (k === null || L.nny > 0) { /* no continuation or no yieldable? */
c.nresults = nresults; /* do a 'conventional' protected call */
status = ldo.luaD_pcall(L, f_call, c, c.funcOff, func);
} else { /* prepare continuation (call is already protected by 'resume') */
let ci = L.ci;
ci.c_k = k; /* prepare continuation (call is already protected by 'resume') */
ci.c_ctx = ctx; /* prepare continuation (call is already protected by 'resume') */
/* save information for error recovery */
ci.extra = c.funcOff;
ci.c_old_errfunc = L.errfunc;
L.errfunc = func;
ci.callstatus &= ~lstate.CIST_OAH | L.allowhook;
ci.callstatus |= lstate.CIST_YPCALL; /* function can do error recovery */
ldo.luaD_call(L, c.funcOff, nresults); /* do the call */
ci.callstatus &= ~lstate.CIST_YPCALL;
L.errfunc = ci.c_old_errfunc;
status = TS.LUA_OK;
}
if (nresults === defs.LUA_MULTRET && L.ci.top < L.top)
L.ci.top = L.top;
return status;
};
const lua_pcall = function(L, n, r, f) {
return lua_pcallk(L, n, r, f, 0, null);
};
/*
** miscellaneous functions
*/
const lua_error = function(L) {
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
ldebug.luaG_errormsg(L);
};
const lua_next = function(L, idx) {
let t = index2addr(L, idx);
assert(t.ttistable(), "table expected");
L.stack[L.top] = new TValue();
let more = ltable.luaH_next(L, t.value, L.top - 1);
if (more) {
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
return 1;
} else {
delete L.stack[L.top];
delete L.stack[--L.top];
return 0;
}
};
const lua_concat = function(L, n) {
assert(n < L.top - L.ci.funcOff, "not enough elements in the stack");
if (n >= 2)
lvm.luaV_concat(L, n);
else if (n === 0) {
lobject.pushsvalue2s(L, lstring.luaS_bless(L, []));
assert(L.top <= L.ci.top, "stack overflow");
}
};
const lua_len = function(L, idx) {
let t = index2addr(L, idx);
let tv = new TValue();
lvm.luaV_objlen(L, tv, t);
L.stack[L.top] = tv;
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const getupvalref = function(L, fidx, n) {
let fi = index2addr(L, fidx);
assert(fi.ttisLclosure(), "Lua function expected");
let f = fi.value;
assert(1 <= n && n <= f.p.upvalues.length, "invalid upvalue index");
return {
closure: f,
upval: f.upvals[n - 1],
upvalOff: n - 1
};
};
const lua_upvalueid = function(L, fidx, n) {
let fi = index2addr(L, fidx);
switch (fi.ttype()) {
case CT.LUA_TLCL: { /* lua closure */
return getupvalref(L, fidx, n).upval;
}
case CT.LUA_TCCL: { /* C closure */
let f = fi.value;
assert(1 <= n && n <= f.nupvalues, "invalid upvalue index");
return f.upvalue[n - 1];
}
default: {
assert(false, "closure expected");
return null;
}
}
};
const lua_upvaluejoin = function(L, fidx1, n1, fidx2, n2) {
let ref1 = getupvalref(L, fidx1, n1);
let ref2 = getupvalref(L, fidx2, n2);
let up1 = ref1.upval;
let up2 = ref2.upval;
let f1 = ref1.closure;
assert(up1.refcount > 0);
up1.refcount--;
f1.upvals[ref1.upvalOff] = up2;
up2.refcount++;
};
// This functions are only there for compatibility purposes
const lua_gc = function () {};
const lua_getallocf = function () {
console.warn("lua_getallocf is not available");
return 0;
};
const lua_setallocf = function () {
console.warn("lua_setallocf is not available");
return 0;
};
const lua_getextraspace = function () {
console.warn("lua_getextraspace is not available");
return 0;
};
module.exports.index2addr = index2addr;
module.exports.index2addr_ = index2addr_;
module.exports.lua_absindex = lua_absindex;
module.exports.lua_arith = lua_arith;
module.exports.lua_atpanic = lua_atpanic;
module.exports.lua_atnativeerror = lua_atnativeerror;
module.exports.lua_call = lua_call;
module.exports.lua_callk = lua_callk;
module.exports.lua_checkstack = lua_checkstack;
module.exports.lua_compare = lua_compare;
module.exports.lua_concat = lua_concat;
module.exports.lua_copy = lua_copy;
module.exports.lua_createtable = lua_createtable;
module.exports.lua_dump = lua_dump;
module.exports.lua_error = lua_error;
module.exports.lua_gc = lua_gc;
module.exports.lua_getallocf = lua_getallocf;
module.exports.lua_getextraspace = lua_getextraspace;
module.exports.lua_getfield = lua_getfield;
module.exports.lua_getglobal = lua_getglobal;
module.exports.lua_geti = lua_geti;
module.exports.lua_getmetatable = lua_getmetatable;
module.exports.lua_gettable = lua_gettable;
module.exports.lua_gettop = lua_gettop;
module.exports.lua_getupvalue = lua_getupvalue;
module.exports.lua_getuservalue = lua_getuservalue;
module.exports.lua_insert = lua_insert;
module.exports.lua_isboolean = lua_isboolean;
module.exports.lua_iscfunction = lua_iscfunction;
module.exports.lua_isfunction = lua_isfunction;
module.exports.lua_isinteger = lua_isinteger;
module.exports.lua_islightuserdata = lua_islightuserdata;
module.exports.lua_isnil = lua_isnil;
module.exports.lua_isnone = lua_isnone;
module.exports.lua_isnoneornil = lua_isnoneornil;
module.exports.lua_isnumber = lua_isnumber;
module.exports.lua_isproxy = lua_isproxy;
module.exports.lua_isstring = lua_isstring;
module.exports.lua_istable = lua_istable;
module.exports.lua_isthread = lua_isthread;
module.exports.lua_isuserdata = lua_isuserdata;
module.exports.lua_len = lua_len;
module.exports.lua_load = lua_load;
module.exports.lua_newtable = lua_newtable;
module.exports.lua_newuserdata = lua_newuserdata;
module.exports.lua_next = lua_next;
module.exports.lua_pcall = lua_pcall;
module.exports.lua_pcallk = lua_pcallk;
module.exports.lua_pop = lua_pop;
module.exports.lua_pushboolean = lua_pushboolean;
module.exports.lua_pushcclosure = lua_pushcclosure;
module.exports.lua_pushcfunction = lua_pushcfunction;
module.exports.lua_pushfstring = lua_pushfstring;
module.exports.lua_pushglobaltable = lua_pushglobaltable;
module.exports.lua_pushinteger = lua_pushinteger;
module.exports.lua_pushjsclosure = lua_pushjsclosure;
module.exports.lua_pushjsfunction = lua_pushjsfunction;
module.exports.lua_pushlightuserdata = lua_pushlightuserdata;
module.exports.lua_pushliteral = lua_pushliteral;
module.exports.lua_pushlstring = lua_pushlstring;
module.exports.lua_pushnil = lua_pushnil;
module.exports.lua_pushnumber = lua_pushnumber;
module.exports.lua_pushstring = lua_pushstring;
module.exports.lua_pushthread = lua_pushthread;
module.exports.lua_pushvalue = lua_pushvalue;
module.exports.lua_pushvfstring = lua_pushvfstring;
module.exports.lua_rawequal = lua_rawequal;
module.exports.lua_rawget = lua_rawget;
module.exports.lua_rawgeti = lua_rawgeti;
module.exports.lua_rawgetp = lua_rawgetp;
module.exports.lua_rawlen = lua_rawlen;
module.exports.lua_rawset = lua_rawset;
module.exports.lua_rawseti = lua_rawseti;
module.exports.lua_rawsetp = lua_rawsetp;
module.exports.lua_register = lua_register;
module.exports.lua_remove = lua_remove;
module.exports.lua_replace = lua_replace;
module.exports.lua_rotate = lua_rotate;
module.exports.lua_setallocf = lua_setallocf;
module.exports.lua_setfield = lua_setfield;
module.exports.lua_setglobal = lua_setglobal;
module.exports.lua_seti = lua_seti;
module.exports.lua_setmetatable = lua_setmetatable;
module.exports.lua_settable = lua_settable;
module.exports.lua_settop = lua_settop;
module.exports.lua_setupvalue = lua_setupvalue;
module.exports.lua_setuservalue = lua_setuservalue;
module.exports.lua_status = lua_status;
module.exports.lua_stringtonumber = lua_stringtonumber;
module.exports.lua_toboolean = lua_toboolean;
module.exports.lua_tocfunction = lua_tocfunction;
module.exports.lua_todataview = lua_todataview;
module.exports.lua_tointeger = lua_tointeger;
module.exports.lua_tointegerx = lua_tointegerx;
module.exports.lua_tojsstring = lua_tojsstring;
module.exports.lua_toljsstring = lua_toljsstring;
module.exports.lua_tolstring = lua_tolstring;
module.exports.lua_tonumber = lua_tonumber;
module.exports.lua_tonumberx = lua_tonumberx;
module.exports.lua_topointer = lua_topointer;
module.exports.lua_toproxy = lua_toproxy;
module.exports.lua_tostring = lua_tostring;
module.exports.lua_tothread = lua_tothread;
module.exports.lua_touserdata = lua_touserdata;
module.exports.lua_type = lua_type;
module.exports.lua_typename = lua_typename;
module.exports.lua_upvalueid = lua_upvalueid;
module.exports.lua_upvaluejoin = lua_upvaluejoin;
module.exports.lua_version = lua_version;
module.exports.lua_xmove = lua_xmove;
/***/ }),
/* 38 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const ldebug = __webpack_require__(23);
const ldo = __webpack_require__(13);
const ldump = __webpack_require__(87);
const lfunc = __webpack_require__(24);
const lobject = __webpack_require__(7);
const lstate = __webpack_require__(25);
const lstring = __webpack_require__(17);
const ltm = __webpack_require__(31);
const luaconf = __webpack_require__(22);
const lvm = __webpack_require__(32);
const ltable = __webpack_require__(16);
const lzio = __webpack_require__(36);
const MAXUPVAL = lfunc.MAXUPVAL;
const CT = defs.constant_types;
const TS = defs.thread_status;
const TValue = lobject.TValue;
const CClosure = lobject.CClosure;
const isvalid = function(o) {
return o !== lobject.luaO_nilobject;
};
const lua_version = function(L) {
if (L === null) return defs.LUA_VERSION_NUM;
else return L.l_G.version;
};
const lua_atpanic = function(L, panicf) {
let old = L.l_G.panic;
L.l_G.panic = panicf;
return old;
};
const lua_atnativeerror = function(L, errorf) {
let old = L.l_G.atnativeerror;
L.l_G.atnativeerror = errorf;
return old;
};
// Return value for idx on stack
const index2addr = function(L, idx) {
let ci = L.ci;
if (idx > 0) {
let o = ci.funcOff + idx;
assert(idx <= ci.top - (ci.funcOff + 1), "unacceptable index");
if (o >= L.top) return lobject.luaO_nilobject;
else return L.stack[o];
} else if (idx > defs.LUA_REGISTRYINDEX) {
assert(idx !== 0 && -idx <= L.top, "invalid index");
return L.stack[L.top + idx];
} else if (idx === defs.LUA_REGISTRYINDEX) {
return L.l_G.l_registry;
} else { /* upvalues */
idx = defs.LUA_REGISTRYINDEX - idx;
assert(idx <= MAXUPVAL + 1, "upvalue index too large");
if (ci.func.ttislcf()) /* light C function? */
return lobject.luaO_nilobject; /* it has no upvalues */
else {
return idx <= ci.func.value.nupvalues ? ci.func.value.upvalue[idx - 1] : lobject.luaO_nilobject;
}
}
};
// Like index2addr but returns the index on stack; doesn't allow pseudo indices
const index2addr_ = function(L, idx) {
let ci = L.ci;
if (idx > 0) {
let o = ci.funcOff + idx;
assert(idx <= ci.top - (ci.funcOff + 1), "unacceptable index");
if (o >= L.top) return null;
else return o;
} else if (idx > defs.LUA_REGISTRYINDEX) {
assert(idx !== 0 && -idx <= L.top, "invalid index");
return L.top + idx;
} else { /* registry or upvalue */
throw Error("attempt to use pseudo-index");
}
};
const lua_checkstack = function(L, n) {
let res;
let ci = L.ci;
assert(n >= 0, "negative 'n'");
if (L.stack_last - L.top > n) /* stack large enough? */
res = true;
else { /* no; need to grow stack */
let inuse = L.top + lstate.EXTRA_STACK;
if (inuse > luaconf.LUAI_MAXSTACK - n) /* can grow without overflow? */
res = false; /* no */
else { /* try to grow stack */
ldo.luaD_growstack(L, n);
res = true;
}
}
if (res && ci.top < L.top + n)
ci.top = L.top + n; /* adjust frame top */
return res;
};
const lua_xmove = function(from, to, n) {
if (from === to) return;
assert(n < (from.top - from.ci.funcOff), "not enough elements in the stack");
assert(from.l_G === to.l_G, "moving among independent states");
assert(to.ci.top - to.top >= n, "stack overflow");
from.top -= n;
for (let i = 0; i < n; i++) {
to.stack[to.top] = new lobject.TValue();
lobject.setobj2s(to, to.top, from.stack[from.top + i]);
delete from.stack[from.top + i];
to.top++;
}
};
/*
** basic stack manipulation
*/
/*
** convert an acceptable stack index into an absolute index
*/
const lua_absindex = function(L, idx) {
return (idx > 0 || idx <= defs.LUA_REGISTRYINDEX)
? idx
: (L.top - L.ci.funcOff) + idx;
};
const lua_gettop = function(L) {
return L.top - (L.ci.funcOff + 1);
};
const lua_pushvalue = function(L, idx) {
lobject.pushobj2s(L, index2addr(L, idx));
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_settop = function(L, idx) {
let func = L.ci.funcOff;
let newtop;
if (idx >= 0) {
assert(idx <= L.stack_last - (func + 1), "new top too large");
newtop = func + 1 + idx;
} else {
assert(-(idx + 1) <= L.top - (func + 1), "invalid new top");
newtop = L.top + idx + 1; /* 'subtract' index (index is negative) */
}
ldo.adjust_top(L, newtop);
};
const lua_pop = function(L, n) {
lua_settop(L, -n - 1);
};
const reverse = function(L, from, to) {
for (; from < to; from++, to--) {
let fromtv = L.stack[from];
let temp = new TValue(fromtv.type, fromtv.value);
lobject.setobjs2s(L, from, to);
lobject.setobj2s(L, to, temp);
}
};
/*
** Let x = AB, where A is a prefix of length 'n'. Then,
** rotate x n === BA. But BA === (A^r . B^r)^r.
*/
const lua_rotate = function(L, idx, n) {
let t = L.top - 1;
let pIdx = index2addr_(L, idx);
let p = L.stack[pIdx];
assert(isvalid(p) && idx > defs.LUA_REGISTRYINDEX, "index not in the stack");
assert((n >= 0 ? n : -n) <= (t - pIdx + 1), "invalid 'n'");
let m = n >= 0 ? t - n : pIdx - n - 1; /* end of prefix */
reverse(L, pIdx, m);
reverse(L, m + 1, L.top - 1);
reverse(L, pIdx, L.top - 1);
};
const lua_copy = function(L, fromidx, toidx) {
let from = index2addr(L, fromidx);
index2addr(L, toidx).setfrom(from);
};
const lua_remove = function(L, idx) {
lua_rotate(L, idx, -1);
lua_pop(L, 1);
};
const lua_insert = function(L, idx) {
lua_rotate(L, idx, 1);
};
const lua_replace = function(L, idx) {
lua_copy(L, -1, idx);
lua_pop(L, 1);
};
/*
** push functions (JS -> stack)
*/
const lua_pushnil = function(L) {
L.stack[L.top] = new TValue(CT.LUA_TNIL, null);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushnumber = function(L, n) {
assert(typeof n === "number");
L.stack[L.top] = new TValue(CT.LUA_TNUMFLT, n);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushinteger = function(L, n) {
assert(typeof n === "number" && (n|0) === n);
L.stack[L.top] = new TValue(CT.LUA_TNUMINT, n);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushlstring = function(L, s, len) {
assert(typeof len === "number");
let ts;
if (len === 0) {
ts = lstring.luaS_bless(L, []);
} else {
assert(defs.is_luastring(s) && s.length >= len, "lua_pushlstring expects array of byte");
ts = lstring.luaS_bless(L, s.slice(0, len));
}
lobject.pushsvalue2s(L, ts);
assert(L.top <= L.ci.top, "stack overflow");
return ts.value;
};
const lua_pushstring = function (L, s) {
assert(defs.is_luastring(s) || s === undefined || s === null, "lua_pushstring expects array of byte");
if (s === undefined || s === null) {
L.stack[L.top] = new TValue(CT.LUA_TNIL, null);
L.top++;
} else {
let ts = lstring.luaS_new(L, s);
lobject.pushsvalue2s(L, ts);
s = ts.getstr(); /* internal copy */
}
assert(L.top <= L.ci.top, "stack overflow");
return s;
};
const lua_pushvfstring = function (L, fmt, argp) {
assert(defs.is_luastring(fmt));
return lobject.luaO_pushvfstring(L, fmt, argp);
};
const lua_pushfstring = function (L, fmt, ...argp) {
assert(defs.is_luastring(fmt));
return lobject.luaO_pushvfstring(L, fmt, argp);
};
/* Similar to lua_pushstring, but takes a JS string */
const lua_pushliteral = function (L, s) {
assert(typeof s === "string" || s === undefined || s === null, "lua_pushliteral expects a JS string");
if (s === undefined || s === null) {
L.stack[L.top] = new TValue(CT.LUA_TNIL, null);
L.top++;
} else {
let ts = lstring.luaS_newliteral(L, s);
lobject.pushsvalue2s(L, ts);
s = ts.getstr(); /* internal copy */
}
assert(L.top <= L.ci.top, "stack overflow");
return s;
};
const lua_pushcclosure = function(L, fn, n) {
assert(typeof fn === "function");
assert(typeof n === "number");
if (n === 0)
L.stack[L.top] = new TValue(CT.LUA_TLCF, fn);
else {
assert(n < L.top - L.ci.funcOff, "not enough elements in the stack");
assert(n <= MAXUPVAL, "upvalue index too large");
let cl = new CClosure(L, fn, n);
for (let i=0; i<n; i++)
cl.upvalue[i].setfrom(L.stack[L.top - n + i]);
for (let i=1; i<n; i++)
delete L.stack[--L.top];
if (n>0)
--L.top;
L.stack[L.top].setclCvalue(cl);
}
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushjsclosure = lua_pushcclosure;
const lua_pushcfunction = function(L, fn) {
lua_pushcclosure(L, fn, 0);
};
const lua_pushjsfunction = lua_pushcfunction;
const lua_pushboolean = function(L, b) {
L.stack[L.top] = new TValue(CT.LUA_TBOOLEAN, b ? true : false);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushlightuserdata = function(L, p) {
L.stack[L.top] = new TValue(CT.LUA_TLIGHTUSERDATA, p);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const lua_pushthread = function(L) {
L.stack[L.top] = new TValue(CT.LUA_TTHREAD, L);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
return L.l_G.mainthread === L;
};
const lua_pushglobaltable = function(L) {
lua_rawgeti(L, defs.LUA_REGISTRYINDEX, defs.LUA_RIDX_GLOBALS);
};
/*
** set functions (stack -> Lua)
*/
/*
** t[k] = value at the top of the stack (where 'k' is a string)
*/
const auxsetstr = function(L, t, k) {
assert(defs.is_luastring(k), "key must be an array of bytes");
let str = lstring.luaS_new(L, k);
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
lobject.pushsvalue2s(L, str); /* push 'str' (to make it a TValue) */
assert(L.top <= L.ci.top, "stack overflow");
lvm.settable(L, t, L.stack[L.top - 1], L.stack[L.top - 2]);
/* pop value and key */
delete L.stack[--L.top];
delete L.stack[--L.top];
};
const lua_setglobal = function(L, name) {
auxsetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, defs.LUA_RIDX_GLOBALS), name);
};
const lua_setmetatable = function(L, objindex) {
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let mt;
let obj = index2addr(L, objindex);
if (L.stack[L.top - 1].ttisnil())
mt = null;
else {
assert(L.stack[L.top - 1].ttistable(), "table expected");
mt = L.stack[L.top - 1].value;
}
switch (obj.ttnov()) {
case CT.LUA_TUSERDATA:
case CT.LUA_TTABLE: {
obj.value.metatable = mt;
break;
}
default: {
L.l_G.mt[obj.ttnov()] = mt;
break;
}
}
delete L.stack[--L.top];
return true;
};
const lua_settable = function(L, idx) {
assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack");
let t = index2addr(L, idx);
lvm.settable(L, t, L.stack[L.top - 2], L.stack[L.top - 1]);
delete L.stack[--L.top];
delete L.stack[--L.top];
};
const lua_setfield = function(L, idx, k) {
auxsetstr(L, index2addr(L, idx), k);
};
const lua_seti = function(L, idx, n) {
assert(typeof n === "number" && (n|0) === n);
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let t = index2addr(L, idx);
L.stack[L.top] = new TValue(CT.LUA_TNUMINT, n);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
lvm.settable(L, t, L.stack[L.top - 1], L.stack[L.top - 2]);
/* pop value and key */
delete L.stack[--L.top];
delete L.stack[--L.top];
};
const lua_rawset = function(L, idx) {
assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack");
let o = index2addr(L, idx);
assert(o.ttistable(), "table expected");
let k = L.stack[L.top - 2];
let v = L.stack[L.top - 1];
if (v.ttisnil()) {
ltable.luaH_delete(L, o.value, k);
} else {
let slot = ltable.luaH_set(L, o.value, k);
slot.setfrom(v);
}
ltable.invalidateTMcache(o.value);
delete L.stack[--L.top];
delete L.stack[--L.top];
};
const lua_rawseti = function(L, idx, n) {
assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack");
let o = index2addr(L, idx);
assert(o.ttistable(), "table expected");
ltable.luaH_setint(o.value, n, L.stack[L.top - 1]);
delete L.stack[--L.top];
};
const lua_rawsetp = function(L, idx, p) {
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let o = index2addr(L, idx);
assert(L, o.ttistable(), "table expected");
let k = new TValue(CT.LUA_TLIGHTUSERDATA, p);
let v = L.stack[L.top - 1];
if (v.ttisnil()) {
ltable.luaH_delete(L, o.value, k);
} else {
let slot = ltable.luaH_set(L, o.value, k);
slot.setfrom(v);
}
delete L.stack[--L.top];
};
/*
** get functions (Lua -> stack)
*/
const auxgetstr = function(L, t, k) {
assert(defs.is_luastring(k), "key must be an array of bytes");
let str = lstring.luaS_new(L, k);
lobject.pushsvalue2s(L, str);
assert(L.top <= L.ci.top, "stack overflow");
lvm.luaV_gettable(L, t, L.stack[L.top - 1], L.top - 1);
return L.stack[L.top - 1].ttnov();
};
const lua_rawgeti = function(L, idx, n) {
let t = index2addr(L, idx);
assert(t.ttistable(), "table expected");
lobject.pushobj2s(L, ltable.luaH_getint(t.value, n));
assert(L.top <= L.ci.top, "stack overflow");
return L.stack[L.top - 1].ttnov();
};
const lua_rawgetp = function(L, idx, p) {
let t = index2addr(L, idx);
assert(t.ttistable(), "table expected");
let k = new TValue(CT.LUA_TLIGHTUSERDATA, p);
lobject.pushobj2s(L, ltable.luaH_get(L, t.value, k));
assert(L.top <= L.ci.top, "stack overflow");
return L.stack[L.top - 1].ttnov();
};
const lua_rawget = function(L, idx) {
let t = index2addr(L, idx);
assert(t.ttistable(t), "table expected");
lobject.setobj2s(L, L.top - 1, ltable.luaH_get(L, t.value, L.stack[L.top - 1]));
return L.stack[L.top - 1].ttnov();
};
// narray and nrec are mostly useless for this implementation
const lua_createtable = function(L, narray, nrec) {
let t = new lobject.TValue(CT.LUA_TTABLE, ltable.luaH_new(L));
L.stack[L.top] = t;
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const luaS_newudata = function(L, size) {
return new lobject.Udata(L, size);
};
const lua_newuserdata = function(L, size) {
let u = luaS_newudata(L, size);
L.stack[L.top] = new lobject.TValue(CT.LUA_TUSERDATA, u);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
return u.data;
};
const aux_upvalue = function(L, fi, n) {
switch(fi.ttype()) {
case CT.LUA_TCCL: { /* C closure */
let f = fi.value;
if (!(1 <= n && n <= f.nupvalues)) return null;
return {
name: [],
val: f.upvalue[n-1]
};
}
case CT.LUA_TLCL: { /* Lua closure */
let f = fi.value;
let p = f.p;
if (!(1 <= n && n <= p.upvalues.length)) return null;
let name = p.upvalues[n-1].name;
return {
name: name ? name.getstr() : defs.to_luastring("(*no name)", true),
val: f.upvals[n-1].v
};
}
default: return null; /* not a closure */
}
};
const lua_getupvalue = function(L, funcindex, n) {
let up = aux_upvalue(L, index2addr(L, funcindex), n);
if (up) {
let name = up.name;
let val = up.val;
lobject.pushobj2s(L, val);
assert(L.top <= L.ci.top, "stack overflow");
return name;
}
return null;
};
const lua_setupvalue = function(L, funcindex, n) {
let fi = index2addr(L, funcindex);
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let aux = aux_upvalue(L, fi, n);
if (aux) {
let name = aux.name;
let val = aux.val;
val.setfrom(L.stack[L.top-1]);
delete L.stack[--L.top];
return name;
}
return null;
};
const lua_newtable = function(L) {
lua_createtable(L, 0, 0);
};
const lua_register = function(L, n, f) {
lua_pushcfunction(L, f);
lua_setglobal(L, n);
};
const lua_getmetatable = function(L, objindex) {
let obj = index2addr(L, objindex);
let mt;
let res = false;
switch (obj.ttnov()) {
case CT.LUA_TTABLE:
case CT.LUA_TUSERDATA:
mt = obj.value.metatable;
break;
default:
mt = L.l_G.mt[obj.ttnov()];
break;
}
if (mt !== null && mt !== undefined) {
L.stack[L.top] = new TValue(CT.LUA_TTABLE, mt);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
res = true;
}
return res;
};
const lua_getuservalue = function(L, idx) {
let o = index2addr(L, idx);
assert(L, o.ttisfulluserdata(), "full userdata expected");
let uv = o.value.uservalue;
L.stack[L.top] = new TValue(uv.type, uv.value);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
return L.stack[L.top - 1].ttnov();
};
const lua_gettable = function(L, idx) {
let t = index2addr(L, idx);
lvm.luaV_gettable(L, t, L.stack[L.top - 1], L.top - 1);
return L.stack[L.top - 1].ttnov();
};
const lua_getfield = function(L, idx, k) {
return auxgetstr(L, index2addr(L, idx), k);
};
const lua_geti = function(L, idx, n) {
assert(typeof n === "number" && (n|0) === n);
let t = index2addr(L, idx);
L.stack[L.top] = new TValue(CT.LUA_TNUMINT, n);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
lvm.luaV_gettable(L, t, L.stack[L.top - 1], L.top - 1);
return L.stack[L.top - 1].ttnov();
};
const lua_getglobal = function(L, name) {
return auxgetstr(L, ltable.luaH_getint(L.l_G.l_registry.value, defs.LUA_RIDX_GLOBALS), name);
};
/*
** access functions (stack -> JS)
*/
const lua_toboolean = function(L, idx) {
let o = index2addr(L, idx);
return !o.l_isfalse();
};
const lua_tolstring = function(L, idx) {
let o = index2addr(L, idx);
if (!o.ttisstring()) {
if (!lvm.cvt2str(o)) { /* not convertible? */
return null;
}
lobject.luaO_tostring(L, o);
}
return o.svalue();
};
const lua_tostring = lua_tolstring;
const lua_toljsstring = function(L, idx) {
let o = index2addr(L, idx);
if (!o.ttisstring()) {
if (!lvm.cvt2str(o)) { /* not convertible? */
return null;
}
lobject.luaO_tostring(L, o);
}
return o.jsstring();
};
const lua_tojsstring = lua_toljsstring;
const lua_todataview = function(L, idx) {
let o = index2addr(L, idx);
if (!o.ttisstring()) {
if (!lvm.cvt2str(o)) { /* not convertible? */
return null;
}
lobject.luaO_tostring(L, o);
}
let dv = new DataView(new ArrayBuffer(o.vslen()));
o.svalue().forEach((e, i) => dv.setUint8(i, e, true));
return dv;
};
const lua_rawlen = function(L, idx) {
let o = index2addr(L, idx);
switch (o.ttype()) {
case CT.LUA_TSHRSTR:
case CT.LUA_TLNGSTR:
return o.vslen();
case CT.LUA_TUSERDATA:
return o.value.len;
case CT.LUA_TTABLE:
return ltable.luaH_getn(o.value);
default:
return 0;
}
};
const lua_tocfunction = function(L, idx) {
let o = index2addr(L, idx);
if (o.ttislcf() || o.ttisCclosure()) return o.value;
else return null; /* not a C function */
};
const lua_tointeger = function(L, idx) {
return lvm.tointeger(index2addr(L, idx));
};
const lua_tonumber = function(L, idx) {
let n = lvm.tonumber(index2addr(L, idx));
return n === false ? 0 : n;
};
const lua_tonumberx = function(L, idx) {
return lvm.tonumber(index2addr(L, idx));
};
const lua_touserdata = function(L, idx) {
let o = index2addr(L, idx);
switch (o.ttnov()) {
case CT.LUA_TUSERDATA:
return o.value.data;
case CT.LUA_TLIGHTUSERDATA:
return o.value;
default: return null;
}
};
const lua_tothread = function(L, idx) {
let o = index2addr(L, idx);
return o.ttisthread() ? o.value : null;
};
const lua_topointer = function(L, idx) {
let o = index2addr(L, idx);
switch (o.ttype()) {
case CT.LUA_TTABLE:
case CT.LUA_TLCL:
case CT.LUA_TCCL:
case CT.LUA_TLCF:
case CT.LUA_TTHREAD:
case CT.LUA_TUSERDATA: /* note: this differs in behaviour to reference lua implementation */
case CT.LUA_TLIGHTUSERDATA:
return o.value;
default:
return null;
}
};
/* A proxy is a function that the same lua value to the given lua state. */
/* Having a weakmap of created proxies was only way I could think of to provide an 'isproxy' function */
const seen = new WeakMap();
/* is the passed object a proxy? is it from the given state? (if passed) */
const lua_isproxy = function(p, L) {
let G = seen.get(p);
if (!G)
return false;
return (L === null) || (L.l_G === G);
};
/* Use 'create_proxy' helper function so that 'L' is not in scope */
const create_proxy = function(G, type, value) {
let proxy = function(L) {
assert(L instanceof lstate.lua_State && G === L.l_G, "must be from same global state");
L.stack[L.top] = new TValue(type, value);
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
seen.set(proxy, G);
return proxy;
};
const lua_toproxy = function(L, idx) {
let tv = index2addr(L, idx);
/* pass broken down tv incase it is an upvalue index */
return create_proxy(L.l_G, tv.type, tv.value);
};
const lua_compare = function(L, index1, index2, op) {
let o1 = index2addr(L, index1);
let o2 = index2addr(L, index2);
let i = 0;
if (isvalid(o1) && isvalid(o2)) {
switch (op) {
case defs.LUA_OPEQ: i = lvm.luaV_equalobj(L, o1, o2); break;
case defs.LUA_OPLT: i = lvm.luaV_lessthan(L, o1, o2); break;
case defs.LUA_OPLE: i = lvm.luaV_lessequal(L, o1, o2); break;
default: assert(false, "invalid option");
}
}
return i;
};
const lua_stringtonumber = function(L, s) {
let tv = lobject.luaO_str2num(s);
if (tv) {
L.stack[L.top] = tv;
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
return s.length+1;
}
return 0;
};
const lua_tointegerx = function(L, idx) {
return lvm.tointeger(index2addr(L, idx));
};
const f_call = function(L, ud) {
ldo.luaD_callnoyield(L, ud.funcOff, ud.nresults);
};
const lua_type = function(L, idx) {
let o = index2addr(L, idx);
return isvalid(o) ? o.ttnov() : CT.LUA_TNONE;
};
const lua_typename = function(L, t) {
assert(CT.LUA_TNONE <= t && t < CT.LUA_NUMTAGS, "invalid tag");
return ltm.ttypename(t);
};
const lua_iscfunction = function(L, idx) {
let o = index2addr(L, idx);
return o.ttislcf(o) || o.ttisCclosure();
};
const lua_isnil = function(L, n) {
return lua_type(L, n) === CT.LUA_TNIL;
};
const lua_isboolean = function(L, n) {
return lua_type(L, n) === CT.LUA_TBOOLEAN;
};
const lua_isnone = function(L, n) {
return lua_type(L, n) === CT.LUA_TNONE;
};
const lua_isnoneornil = function(L, n) {
return lua_type(L, n) <= 0;
};
const lua_istable = function(L, idx) {
return index2addr(L, idx).ttistable();
};
const lua_isinteger = function(L, idx) {
return index2addr(L, idx).ttisinteger();
};
const lua_isnumber = function(L, idx) {
return lvm.tonumber(index2addr(L, idx)) !== false;
};
const lua_isstring = function(L, idx) {
let o = index2addr(L, idx);
return o.ttisstring() || lvm.cvt2str(o);
};
const lua_isuserdata = function(L, idx) {
let o = index2addr(L, idx);
return o.ttisfulluserdata(o) || o.ttislightuserdata();
};
const lua_isthread = function(L, idx) {
return lua_type(L, idx) === CT.LUA_TTHREAD;
};
const lua_isfunction = function(L, idx) {
return lua_type(L, idx) === CT.LUA_TFUNCTION;
};
const lua_islightuserdata = function(L, idx) {
return lua_type(L, idx) === CT.LUA_TLIGHTUSERDATA;
};
const lua_rawequal = function(L, index1, index2) {
let o1 = index2addr(L, index1);
let o2 = index2addr(L, index2);
return isvalid(o1) && isvalid(o2) ? lvm.luaV_equalobj(null, o1, o2) : 0; // TODO: isvalid ?
};
const lua_arith = function(L, op) {
if (op !== defs.LUA_OPUNM && op !== defs.LUA_OPBNOT)
assert(2 < L.top - L.ci.funcOff, "not enough elements in the stack"); /* all other operations expect two operands */
else { /* for unary operations, add fake 2nd operand */
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
lobject.pushobj2s(L, L.stack[L.top-1]);
assert(L.top <= L.ci.top, "stack overflow");
}
/* first operand at top - 2, second at top - 1; result go to top - 2 */
lobject.luaO_arith(L, op, L.stack[L.top - 2], L.stack[L.top - 1], L.stack[L.top - 2]);
delete L.stack[--L.top]; /* remove second operand */
};
/*
** 'load' and 'call' functions (run Lua code)
*/
const lua_load = function(L, reader, data, chunkname, mode) {
assert(defs.is_luastring(chunkname), "lua_load expect an array of byte as chunkname");
assert(mode ? defs.is_luastring(mode) : true, "lua_load expect an array of byte as mode");
if (!chunkname) chunkname = [defs.char["?"]];
let z = new lzio.ZIO(L, reader, data);
let status = ldo.luaD_protectedparser(L, z, chunkname, mode);
if (status === TS.LUA_OK) { /* no errors? */
let f = L.stack[L.top - 1].value; /* get newly created function */
if (f.nupvalues >= 1) { /* does it have an upvalue? */
/* get global table from registry */
let gt = ltable.luaH_getint(L.l_G.l_registry.value, defs.LUA_RIDX_GLOBALS);
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
f.upvals[0].v.setfrom(gt);
}
}
return status;
};
const lua_dump = function(L, writer, data, strip) {
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let o = L.stack[L.top -1];
if (o.ttisLclosure())
return ldump.luaU_dump(L, o.value.p, writer, data, strip);
return 1;
};
const lua_status = function(L) {
return L.status;
};
const lua_setuservalue = function(L, idx) {
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
let o = index2addr(L, idx);
assert(L, o.ttisfulluserdata(), "full userdata expected");
o.value.uservalue.setfrom(L.stack[L.top - 1]);
delete L.stack[--L.top];
};
const lua_callk = function(L, nargs, nresults, ctx, k) {
assert(k === null || !(L.ci.callstatus & lstate.CIST_LUA), "cannot use continuations inside hooks");
assert(nargs + 1 < L.top - L.ci.funcOff, "not enough elements in the stack");
assert(L.status === TS.LUA_OK, "cannot do calls on non-normal thread");
assert(nargs === defs.LUA_MULTRET || (L.ci.top - L.top >= nargs - nresults), "results from function overflow current stack size");
let func = L.top - (nargs + 1);
if (k !== null && L.nny === 0) { /* need to prepare continuation? */
L.ci.c_k = k;
L.ci.c_ctx = ctx;
ldo.luaD_call(L, func, nresults);
} else { /* no continuation or no yieldable */
ldo.luaD_callnoyield(L, func, nresults);
}
if (nresults === defs.LUA_MULTRET && L.ci.top < L.top)
L.ci.top = L.top;
};
const lua_call = function(L, n, r) {
lua_callk(L, n, r, 0, null);
};
const lua_pcallk = function(L, nargs, nresults, errfunc, ctx, k) {
assert(nargs + 1 < L.top - L.ci.funcOff, "not enough elements in the stack");
assert(L.status === TS.LUA_OK, "cannot do calls on non-normal thread");
assert(nargs === defs.LUA_MULTRET || (L.ci.top - L.top >= nargs - nresults), "results from function overflow current stack size");
let c = {
func: null,
funcOff: NaN,
nresults: NaN
};
let status;
let func;
if (errfunc === 0)
func = 0;
else {
// let o = index2addr(L, errfunc);
// TODO: api_checkstackindex(L, errfunc, o);
func = index2addr_(L, errfunc);
}
c.funcOff = L.top - (nargs + 1); /* function to be called */
c.func = L.stack[c.funcOff];
if (k === null || L.nny > 0) { /* no continuation or no yieldable? */
c.nresults = nresults; /* do a 'conventional' protected call */
status = ldo.luaD_pcall(L, f_call, c, c.funcOff, func);
} else { /* prepare continuation (call is already protected by 'resume') */
let ci = L.ci;
ci.c_k = k; /* prepare continuation (call is already protected by 'resume') */
ci.c_ctx = ctx; /* prepare continuation (call is already protected by 'resume') */
/* save information for error recovery */
ci.extra = c.funcOff;
ci.c_old_errfunc = L.errfunc;
L.errfunc = func;
ci.callstatus &= ~lstate.CIST_OAH | L.allowhook;
ci.callstatus |= lstate.CIST_YPCALL; /* function can do error recovery */
ldo.luaD_call(L, c.funcOff, nresults); /* do the call */
ci.callstatus &= ~lstate.CIST_YPCALL;
L.errfunc = ci.c_old_errfunc;
status = TS.LUA_OK;
}
if (nresults === defs.LUA_MULTRET && L.ci.top < L.top)
L.ci.top = L.top;
return status;
};
const lua_pcall = function(L, n, r, f) {
return lua_pcallk(L, n, r, f, 0, null);
};
/*
** miscellaneous functions
*/
const lua_error = function(L) {
assert(1 < L.top - L.ci.funcOff, "not enough elements in the stack");
ldebug.luaG_errormsg(L);
};
const lua_next = function(L, idx) {
let t = index2addr(L, idx);
assert(t.ttistable(), "table expected");
L.stack[L.top] = new TValue();
let more = ltable.luaH_next(L, t.value, L.top - 1);
if (more) {
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
return 1;
} else {
delete L.stack[L.top];
delete L.stack[--L.top];
return 0;
}
};
const lua_concat = function(L, n) {
assert(n < L.top - L.ci.funcOff, "not enough elements in the stack");
if (n >= 2)
lvm.luaV_concat(L, n);
else if (n === 0) {
lobject.pushsvalue2s(L, lstring.luaS_bless(L, []));
assert(L.top <= L.ci.top, "stack overflow");
}
};
const lua_len = function(L, idx) {
let t = index2addr(L, idx);
let tv = new TValue();
lvm.luaV_objlen(L, tv, t);
L.stack[L.top] = tv;
L.top++;
assert(L.top <= L.ci.top, "stack overflow");
};
const getupvalref = function(L, fidx, n) {
let fi = index2addr(L, fidx);
assert(fi.ttisLclosure(), "Lua function expected");
let f = fi.value;
assert(1 <= n && n <= f.p.upvalues.length, "invalid upvalue index");
return {
closure: f,
upval: f.upvals[n - 1],
upvalOff: n - 1
};
};
const lua_upvalueid = function(L, fidx, n) {
let fi = index2addr(L, fidx);
switch (fi.ttype()) {
case CT.LUA_TLCL: { /* lua closure */
return getupvalref(L, fidx, n).upval;
}
case CT.LUA_TCCL: { /* C closure */
let f = fi.value;
assert(1 <= n && n <= f.nupvalues, "invalid upvalue index");
return f.upvalue[n - 1];
}
default: {
assert(false, "closure expected");
return null;
}
}
};
const lua_upvaluejoin = function(L, fidx1, n1, fidx2, n2) {
let ref1 = getupvalref(L, fidx1, n1);
let ref2 = getupvalref(L, fidx2, n2);
let up1 = ref1.upval;
let up2 = ref2.upval;
let f1 = ref1.closure;
assert(up1.refcount > 0);
up1.refcount--;
f1.upvals[ref1.upvalOff] = up2;
up2.refcount++;
};
// This functions are only there for compatibility purposes
const lua_gc = function () {};
const lua_getallocf = function () {
console.warn("lua_getallocf is not available");
return 0;
};
const lua_setallocf = function () {
console.warn("lua_setallocf is not available");
return 0;
};
const lua_getextraspace = function () {
console.warn("lua_getextraspace is not available");
return 0;
};
module.exports.index2addr = index2addr;
module.exports.index2addr_ = index2addr_;
module.exports.lua_absindex = lua_absindex;
module.exports.lua_arith = lua_arith;
module.exports.lua_atpanic = lua_atpanic;
module.exports.lua_atnativeerror = lua_atnativeerror;
module.exports.lua_call = lua_call;
module.exports.lua_callk = lua_callk;
module.exports.lua_checkstack = lua_checkstack;
module.exports.lua_compare = lua_compare;
module.exports.lua_concat = lua_concat;
module.exports.lua_copy = lua_copy;
module.exports.lua_createtable = lua_createtable;
module.exports.lua_dump = lua_dump;
module.exports.lua_error = lua_error;
module.exports.lua_gc = lua_gc;
module.exports.lua_getallocf = lua_getallocf;
module.exports.lua_getextraspace = lua_getextraspace;
module.exports.lua_getfield = lua_getfield;
module.exports.lua_getglobal = lua_getglobal;
module.exports.lua_geti = lua_geti;
module.exports.lua_getmetatable = lua_getmetatable;
module.exports.lua_gettable = lua_gettable;
module.exports.lua_gettop = lua_gettop;
module.exports.lua_getupvalue = lua_getupvalue;
module.exports.lua_getuservalue = lua_getuservalue;
module.exports.lua_insert = lua_insert;
module.exports.lua_isboolean = lua_isboolean;
module.exports.lua_iscfunction = lua_iscfunction;
module.exports.lua_isfunction = lua_isfunction;
module.exports.lua_isinteger = lua_isinteger;
module.exports.lua_islightuserdata = lua_islightuserdata;
module.exports.lua_isnil = lua_isnil;
module.exports.lua_isnone = lua_isnone;
module.exports.lua_isnoneornil = lua_isnoneornil;
module.exports.lua_isnumber = lua_isnumber;
module.exports.lua_isproxy = lua_isproxy;
module.exports.lua_isstring = lua_isstring;
module.exports.lua_istable = lua_istable;
module.exports.lua_isthread = lua_isthread;
module.exports.lua_isuserdata = lua_isuserdata;
module.exports.lua_len = lua_len;
module.exports.lua_load = lua_load;
module.exports.lua_newtable = lua_newtable;
module.exports.lua_newuserdata = lua_newuserdata;
module.exports.lua_next = lua_next;
module.exports.lua_pcall = lua_pcall;
module.exports.lua_pcallk = lua_pcallk;
module.exports.lua_pop = lua_pop;
module.exports.lua_pushboolean = lua_pushboolean;
module.exports.lua_pushcclosure = lua_pushcclosure;
module.exports.lua_pushcfunction = lua_pushcfunction;
module.exports.lua_pushfstring = lua_pushfstring;
module.exports.lua_pushglobaltable = lua_pushglobaltable;
module.exports.lua_pushinteger = lua_pushinteger;
module.exports.lua_pushjsclosure = lua_pushjsclosure;
module.exports.lua_pushjsfunction = lua_pushjsfunction;
module.exports.lua_pushlightuserdata = lua_pushlightuserdata;
module.exports.lua_pushliteral = lua_pushliteral;
module.exports.lua_pushlstring = lua_pushlstring;
module.exports.lua_pushnil = lua_pushnil;
module.exports.lua_pushnumber = lua_pushnumber;
module.exports.lua_pushstring = lua_pushstring;
module.exports.lua_pushthread = lua_pushthread;
module.exports.lua_pushvalue = lua_pushvalue;
module.exports.lua_pushvfstring = lua_pushvfstring;
module.exports.lua_rawequal = lua_rawequal;
module.exports.lua_rawget = lua_rawget;
module.exports.lua_rawgeti = lua_rawgeti;
module.exports.lua_rawgetp = lua_rawgetp;
module.exports.lua_rawlen = lua_rawlen;
module.exports.lua_rawset = lua_rawset;
module.exports.lua_rawseti = lua_rawseti;
module.exports.lua_rawsetp = lua_rawsetp;
module.exports.lua_register = lua_register;
module.exports.lua_remove = lua_remove;
module.exports.lua_replace = lua_replace;
module.exports.lua_rotate = lua_rotate;
module.exports.lua_setallocf = lua_setallocf;
module.exports.lua_setfield = lua_setfield;
module.exports.lua_setglobal = lua_setglobal;
module.exports.lua_seti = lua_seti;
module.exports.lua_setmetatable = lua_setmetatable;
module.exports.lua_settable = lua_settable;
module.exports.lua_settop = lua_settop;
module.exports.lua_setupvalue = lua_setupvalue;
module.exports.lua_setuservalue = lua_setuservalue;
module.exports.lua_status = lua_status;
module.exports.lua_stringtonumber = lua_stringtonumber;
module.exports.lua_toboolean = lua_toboolean;
module.exports.lua_tocfunction = lua_tocfunction;
module.exports.lua_todataview = lua_todataview;
module.exports.lua_tointeger = lua_tointeger;
module.exports.lua_tointegerx = lua_tointegerx;
module.exports.lua_tojsstring = lua_tojsstring;
module.exports.lua_toljsstring = lua_toljsstring;
module.exports.lua_tolstring = lua_tolstring;
module.exports.lua_tonumber = lua_tonumber;
module.exports.lua_tonumberx = lua_tonumberx;
module.exports.lua_topointer = lua_topointer;
module.exports.lua_toproxy = lua_toproxy;
module.exports.lua_tostring = lua_tostring;
module.exports.lua_tothread = lua_tothread;
module.exports.lua_touserdata = lua_touserdata;
module.exports.lua_type = lua_type;
module.exports.lua_typename = lua_typename;
module.exports.lua_upvalueid = lua_upvalueid;
module.exports.lua_upvaluejoin = lua_upvaluejoin;
module.exports.lua_version = lua_version;
module.exports.lua_xmove = lua_xmove;
/***/ }),
/* 39 */
/***/ (function(module, exports, __webpack_require__) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
if (!isString(f)) {
var objects = [];
for (var i = 0; i < arguments.length; i++) {
objects.push(inspect(arguments[i]));
}
return objects.join(' ');
}
var i = 1;
var args = arguments;
var len = args.length;
var str = String(f).replace(formatRegExp, function(x) {
if (x === '%%') return '%';
if (i >= len) return x;
switch (x) {
case '%s': return String(args[i++]);
case '%d': return Number(args[i++]);
case '%j':
try {
return JSON.stringify(args[i++]);
} catch (_) {
return '[Circular]';
}
default:
return x;
}
});
for (var x = args[i]; i < len; x = args[++i]) {
if (isNull(x) || !isObject(x)) {
str += ' ' + x;
} else {
str += ' ' + inspect(x);
}
}
return str;
};
// Mark that a method should not be used.
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
exports.deprecate = function(fn, msg) {
// Allow for deprecating things in the process of starting up.
if (isUndefined(global.process)) {
return function() {
return exports.deprecate(fn, msg).apply(this, arguments);
};
}
if (process.noDeprecation === true) {
return fn;
}
var warned = false;
function deprecated() {
if (!warned) {
if (process.throwDeprecation) {
throw new Error(msg);
} else if (process.traceDeprecation) {
console.trace(msg);
} else {
console.error(msg);
}
warned = true;
}
return fn.apply(this, arguments);
}
return deprecated;
};
var debugs = {};
var debugEnviron;
exports.debuglog = function(set) {
if (isUndefined(debugEnviron))
debugEnviron = process.env.NODE_DEBUG || '';
set = set.toUpperCase();
if (!debugs[set]) {
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
var pid = process.pid;
debugs[set] = function() {
var msg = exports.format.apply(exports, arguments);
console.error('%s %d: %s', set, pid, msg);
};
} else {
debugs[set] = function() {};
}
}
return debugs[set];
};
/**
* Echos the value of a value. Trys to print the value out
* in the best way possible given the different types.
*
* @param {Object} obj The object to print out.
* @param {Object} opts Optional options object that alters the output.
*/
/* legacy: obj, showHidden, depth, colors*/
function inspect(obj, opts) {
// default options
var ctx = {
seen: [],
stylize: stylizeNoColor
};
// legacy...
if (arguments.length >= 3) ctx.depth = arguments[2];
if (arguments.length >= 4) ctx.colors = arguments[3];
if (isBoolean(opts)) {
// legacy...
ctx.showHidden = opts;
} else if (opts) {
// got an "options" object
exports._extend(ctx, opts);
}
// set default options
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
if (isUndefined(ctx.depth)) ctx.depth = 2;
if (isUndefined(ctx.colors)) ctx.colors = false;
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
if (ctx.colors) ctx.stylize = stylizeWithColor;
return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
'bold' : [1, 22],
'italic' : [3, 23],
'underline' : [4, 24],
'inverse' : [7, 27],
'white' : [37, 39],
'grey' : [90, 39],
'black' : [30, 39],
'blue' : [34, 39],
'cyan' : [36, 39],
'green' : [32, 39],
'magenta' : [35, 39],
'red' : [31, 39],
'yellow' : [33, 39]
};
// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'date': 'magenta',
// "name": intentionally not styling
'regexp': 'red'
};
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType];
if (style) {
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
'\u001b[' + inspect.colors[style][1] + 'm';
} else {
return str;
}
}
function stylizeNoColor(str, styleType) {
return str;
}
function arrayToHash(array) {
var hash = {};
array.forEach(function(val, idx) {
hash[val] = true;
});
return hash;
}
function formatValue(ctx, value, recurseTimes) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if (ctx.customInspect &&
value &&
isFunction(value.inspect) &&
// Filter out the util module, it's inspect function is special
value.inspect !== exports.inspect &&
// Also filter out any prototype objects using the circular check.
!(value.constructor && value.constructor.prototype === value)) {
var ret = value.inspect(recurseTimes, ctx);
if (!isString(ret)) {
ret = formatValue(ctx, ret, recurseTimes);
}
return ret;
}
// Primitive types cannot have properties
var primitive = formatPrimitive(ctx, value);
if (primitive) {
return primitive;
}
// Look up the keys of the object.
var keys = Object.keys(value);
var visibleKeys = arrayToHash(keys);
if (ctx.showHidden) {
keys = Object.getOwnPropertyNames(value);
}
// IE doesn't make error fields non-enumerable
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
if (isError(value)
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
return formatError(value);
}
// Some type of object without properties can be shortcutted.
if (keys.length === 0) {
if (isFunction(value)) {
var name = value.name ? ': ' + value.name : '';
return ctx.stylize('[Function' + name + ']', 'special');
}
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {
return ctx.stylize(Date.prototype.toString.call(value), 'date');
}
if (isError(value)) {
return formatError(value);
}
}
var base = '', array = false, braces = ['{', '}'];
// Make Array say that they are Array
if (isArray(value)) {
array = true;
braces = ['[', ']'];
}
// Make functions say that they are functions
if (isFunction(value)) {
var n = value.name ? ': ' + value.name : '';
base = ' [Function' + n + ']';
}
// Make RegExps say that they are RegExps
if (isRegExp(value)) {
base = ' ' + RegExp.prototype.toString.call(value);
}
// Make dates with properties first say the date
if (isDate(value)) {
base = ' ' + Date.prototype.toUTCString.call(value);
}
// Make error with message first say the error
if (isError(value)) {
base = ' ' + formatError(value);
}
if (keys.length === 0 && (!array || value.length == 0)) {
return braces[0] + base + braces[1];
}
if (recurseTimes < 0) {
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
} else {
return ctx.stylize('[Object]', 'special');
}
}
ctx.seen.push(value);
var output;
if (array) {
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
} else {
output = keys.map(function(key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
});
}
ctx.seen.pop();
return reduceToSingleString(output, base, braces);
}
function formatPrimitive(ctx, value) {
if (isUndefined(value))
return ctx.stylize('undefined', 'undefined');
if (isString(value)) {
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"') + '\'';
return ctx.stylize(simple, 'string');
}
if (isNumber(value))
return ctx.stylize('' + value, 'number');
if (isBoolean(value))
return ctx.stylize('' + value, 'boolean');
// For some reason typeof null is "object", so special case here.
if (isNull(value))
return ctx.stylize('null', 'null');
}
function formatError(value) {
return '[' + Error.prototype.toString.call(value) + ']';
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
var output = [];
for (var i = 0, l = value.length; i < l; ++i) {
if (hasOwnProperty(value, String(i))) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
String(i), true));
} else {
output.push('');
}
}
keys.forEach(function(key) {
if (!key.match(/^\d+$/)) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
key, true));
}
});
return output;
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
var name, str, desc;
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
if (desc.get) {
if (desc.set) {
str = ctx.stylize('[Getter/Setter]', 'special');
} else {
str = ctx.stylize('[Getter]', 'special');
}
} else {
if (desc.set) {
str = ctx.stylize('[Setter]', 'special');
}
}
if (!hasOwnProperty(visibleKeys, key)) {
name = '[' + key + ']';
}
if (!str) {
if (ctx.seen.indexOf(desc.value) < 0) {
if (isNull(recurseTimes)) {
str = formatValue(ctx, desc.value, null);
} else {
str = formatValue(ctx, desc.value, recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (array) {
str = str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n').substr(2);
} else {
str = '\n' + str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n');
}
}
} else {
str = ctx.stylize('[Circular]', 'special');
}
}
if (isUndefined(name)) {
if (array && key.match(/^\d+$/)) {
return str;
}
name = JSON.stringify('' + key);
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
name = name.substr(1, name.length - 2);
name = ctx.stylize(name, 'name');
} else {
name = name.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
.replace(/(^"|"$)/g, "'");
name = ctx.stylize(name, 'string');
}
}
return name + ': ' + str;
}
function reduceToSingleString(output, base, braces) {
var numLinesEst = 0;
var length = output.reduce(function(prev, cur) {
numLinesEst++;
if (cur.indexOf('\n') >= 0) numLinesEst++;
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
}, 0);
if (length > 60) {
return braces[0] +
(base === '' ? '' : base + '\n ') +
' ' +
output.join(',\n ') +
' ' +
braces[1];
}
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
return Array.isArray(ar);
}
exports.isArray = isArray;
function isBoolean(arg) {
return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;
function isNull(arg) {
return arg === null;
}
exports.isNull = isNull;
function isNullOrUndefined(arg) {
return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;
function isNumber(arg) {
return typeof arg === 'number';
}
exports.isNumber = isNumber;
function isString(arg) {
return typeof arg === 'string';
}
exports.isString = isString;
function isSymbol(arg) {
return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;
function isUndefined(arg) {
return arg === void 0;
}
exports.isUndefined = isUndefined;
function isRegExp(re) {
return isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return isObject(e) &&
(objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;
function isFunction(arg) {
return typeof arg === 'function';
}
exports.isFunction = isFunction;
function isPrimitive(arg) {
return arg === null ||
typeof arg === 'boolean' ||
typeof arg === 'number' ||
typeof arg === 'string' ||
typeof arg === 'symbol' || // ES6 symbol
typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;
exports.isBuffer = __webpack_require__(68);
function objectToString(o) {
return Object.prototype.toString.call(o);
}
function pad(n) {
return n < 10 ? '0' + n.toString(10) : n.toString(10);
}
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec'];
// 26 Feb 16:19:34
function timestamp() {
var d = new Date();
var time = [pad(d.getHours()),
pad(d.getMinutes()),
pad(d.getSeconds())].join(':');
return [d.getDate(), months[d.getMonth()], time].join(' ');
}
// log is just a thin wrapper to console.log that prepends a timestamp
exports.log = function() {
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
};
/**
* Inherit the prototype methods from one constructor into another.
*
* The Function.prototype.inherits from lang.js rewritten as a standalone
* function (not on Function.prototype). NOTE: If this file is to be loaded
* during bootstrapping this function needs to be rewritten using some native
* functions as prototype setup using normal JavaScript does not work as
* expected during bootstrapping (see mirror.js in r114903).
*
* @param {function} ctor Constructor function which needs to inherit the
* prototype.
* @param {function} superCtor Constructor function to inherit prototype from.
*/
exports.inherits = __webpack_require__(69);
exports._extend = function(origin, add) {
// Don't do anything if add isn't an object
if (!add || !isObject(add)) return origin;
var keys = Object.keys(add);
var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
};
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
/***/ }),
/* 40 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const lisdigit = function(c) {
return /^\d$/.test(String.fromCharCode(c));
};
const lisxdigit = function(c) {
return /^[0-9a-fA-F]$/.test(String.fromCharCode(c));
};
const lisprint = function(c) {
return /^[\x20-\x7E]$/.test(String.fromCharCode(c));
};
const lisspace = function(c) {
return /^\s$/.test(String.fromCharCode(c));
};
const lislalpha = function(c) {
return /^[_a-zA-Z]$/.test(String.fromCharCode(c));
};
const lislalnum = function(c) {
return /^[_a-zA-Z0-9]$/.test(String.fromCharCode(c));
};
module.exports.lisdigit = lisdigit;
module.exports.lislalnum = lislalnum;
module.exports.lislalpha = lislalpha;
module.exports.lisprint = lisprint;
module.exports.lisspace = lisspace;
module.exports.lisxdigit = lisxdigit;
/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const lcode = __webpack_require__(70);
const ldo = __webpack_require__(12);
const lfunc = __webpack_require__(20);
const llex = __webpack_require__(42);
const llimit = __webpack_require__(8);
const lobject = __webpack_require__(5);
const lopcodes = __webpack_require__(28);
const lstring = __webpack_require__(15);
const ltable = __webpack_require__(14);
const BinOpr = lcode.BinOpr;
const OpCodesI = lopcodes.OpCodesI;
const Proto = lfunc.Proto;
const R = llex.RESERVED;
const UnOpr = lcode.UnOpr;
const char = defs.char;
const MAXVARS = 200;
const hasmultret = function(k) {
return k === expkind.VCALL || k === expkind.VVARARG;
};
const eqstr = function(a, b) {
/* TODO: use plain equality as strings are cached */
return lstring.luaS_eqlngstr(a, b);
};
class BlockCnt {
constructor() {
this.previous = null; /* chain */
this.firstlabel = NaN; /* index of first label in this block */
this.firstgoto = NaN; /* index of first pending goto in this block */
this.nactvar = NaN; /* # active locals outside the block */
this.upval = NaN; /* true if some variable in the block is an upvalue */
this.isloop = NaN; /* true if 'block' is a loop */
}
}
const expkind = {
VVOID: 0, /* when 'expdesc' describes the last expression a list,
this kind means an empty list (so, no expression) */
VNIL: 1, /* constant nil */
VTRUE: 2, /* constant true */
VFALSE: 3, /* constant false */
VK: 4, /* constant in 'k'; info = index of constant in 'k' */
VKFLT: 5, /* floating constant; nval = numerical float value */
VKINT: 6, /* integer constant; nval = numerical integer value */
VNONRELOC: 7, /* expression has its value in a fixed register;
info = result register */
VLOCAL: 8, /* local variable; info = local register */
VUPVAL: 9, /* upvalue variable; info = index of upvalue in 'upvalues' */
VINDEXED: 10, /* indexed variable;
ind.vt = whether 't' is register or upvalue;
ind.t = table register or upvalue;
ind.idx = key's R/K index */
VJMP: 11, /* expression is a test/comparison;
info = pc of corresponding jump instruction */
VRELOCABLE: 12, /* expression can put result in any register;
info = instruction pc */
VCALL: 13, /* expression is a function call; info = instruction pc */
VVARARG: 14 /* vararg expression; info = instruction pc */
};
const vkisvar = function(k) {
return expkind.VLOCAL <= k && k <= expkind.VINDEXED;
};
const vkisinreg = function(k) {
return k === expkind.VNONRELOC || k === expkind.VLOCAL;
};
class expdesc {
constructor() {
this.k = NaN;
this.u = {
ival: NaN, /* for VKINT */
nval: NaN, /* for VKFLT */
info: NaN, /* for generic use */
ind: { /* for indexed variables (VINDEXED) */
idx: NaN, /* index (R/K) */
t: NaN, /* table (register or upvalue) */
vt: NaN /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
}
};
this.t = NaN; /* patch list of 'exit when true' */
this.f = NaN; /* patch list of 'exit when false' */
}
to(e) { // Copy e content to this, cf. luaK_posfix
this.k = e.k;
this.u = e.u;
this.t = e.t;
this.f = e.f;
}
}
class FuncState {
constructor() {
this.f = null; /* current function header */
this.prev = null; /* enclosing function */
this.ls = null; /* lexical state */
this.bl = null; /* chain of current blocks */
this.pc = NaN; /* next position to code (equivalent to 'ncode') */
this.lasttarget = NaN; /* 'label' of last 'jump label' */
this.jpc = NaN; /* list of pending jumps to 'pc' */
this.nk = NaN; /* number of elements in 'k' */
this.np = NaN; /* number of elements in 'p' */
this.firstlocal = NaN; /* index of first local var (in Dyndata array) */
this.nlocvars = NaN; /* number of elements in 'f->locvars' */
this.nactvar = NaN; /* number of active local variables */
this.nups = NaN; /* number of upvalues */
this.freereg = NaN; /* first free register */
}
}
/* description of active local variable */
class Vardesc {
constructor() {
this.idx = NaN; /* variable index in stack */
}
}
/* description of pending goto statements and label statements */
class Labeldesc {
constructor() {
this.name = null; /* label identifier */
this.pc = NaN; /* position in code */
this.line = NaN; /* line where it appeared */
this.nactvar = NaN; /* local level where it appears in current block */
}
}
/* list of labels or gotos */
class Labellist {
constructor() {
this.arr = []; /* array */
this.n = NaN; /* number of entries in use */
this.size = NaN; /* array size */
}
}
/* dynamic structures used by the parser */
class Dyndata {
constructor() {
this.actvar = { /* list of active local variables */
arr: [],
n: NaN,
size: NaN
};
this.gt = new Labellist();
this.label = new Labellist();
}
}
const semerror = function(ls, msg) {
ls.t.token = 0; /* remove "near <token>" from final message */
llex.luaX_syntaxerror(ls, msg);
};
const error_expected = function(ls, token) {
llex.luaX_syntaxerror(ls, lobject.luaO_pushfstring(ls.L, defs.to_luastring("%s expected", true), llex.luaX_token2str(ls, token)));
};
const errorlimit = function(fs, limit, what) {
let L = fs.ls.L;
let line = fs.f.linedefined;
let where = (line === 0)
? defs.to_luastring("main function", true)
: lobject.luaO_pushfstring(L, defs.to_luastring("function at line %d", true), line);
let msg = lobject.luaO_pushfstring(L, defs.to_luastring("too many %s (limit is %d) in %s", true),
what, limit, where);
llex.luaX_syntaxerror(fs.ls, msg);
};
const checklimit = function(fs, v, l, what) {
if (v > l) errorlimit(fs, l, what);
};
const testnext = function(ls, c) {
if (ls.t.token === c) {
llex.luaX_next(ls);
return true;
}
return false;
};
const check = function(ls, c) {
if (ls.t.token !== c)
error_expected(ls, c);
};
const checknext = function(ls, c) {
check(ls, c);
llex.luaX_next(ls);
};
const check_condition = function(ls, c, msg) {
if (!c)
llex.luaX_syntaxerror(ls, msg);
};
const check_match = function(ls, what, who, where) {
if (!testnext(ls, what)) {
if (where === ls.linenumber)
error_expected(ls, what);
else
llex.luaX_syntaxerror(ls, lobject.luaO_pushfstring(ls.L,
defs.to_luastring("%s expected (to close %s at line %d)"),
llex.luaX_token2str(ls, what), llex.luaX_token2str(ls, who), where));
}
};
const str_checkname = function(ls) {
check(ls, R.TK_NAME);
let ts = ls.t.seminfo.ts;
llex.luaX_next(ls);
return ts;
};
const init_exp = function(e, k, i) {
e.f = e.t = lcode.NO_JUMP;
e.k = k;
e.u.info = i;
};
const codestring = function(ls, e, s) {
init_exp(e, expkind.VK, lcode.luaK_stringK(ls.fs, s));
};
const checkname = function(ls, e) {
codestring(ls, e, str_checkname(ls));
};
const registerlocalvar = function(ls, varname) {
let fs = ls.fs;
let f = fs.f;
f.locvars[fs.nlocvars] = new lobject.LocVar();
f.locvars[fs.nlocvars].varname = varname;
return fs.nlocvars++;
};
const new_localvar = function(ls, name) {
let fs = ls.fs;
let dyd = ls.dyd;
let reg = registerlocalvar(ls, name);
checklimit(fs, dyd.actvar.n + 1 - fs.firstlocal, MAXVARS, defs.to_luastring("local variables", true));
dyd.actvar.arr[dyd.actvar.n] = new Vardesc();
dyd.actvar.arr[dyd.actvar.n].idx = reg;
dyd.actvar.n++;
};
const new_localvarliteral = function(ls, name) {
new_localvar(ls, llex.luaX_newstring(ls, defs.to_luastring(name, true)));
};
const getlocvar = function(fs, i) {
let idx = fs.ls.dyd.actvar.arr[fs.firstlocal + i].idx;
assert(idx < fs.nlocvars);
return fs.f.locvars[idx];
};
const adjustlocalvars = function(ls, nvars) {
let fs = ls.fs;
fs.nactvar = fs.nactvar + nvars;
for (; nvars; nvars--)
getlocvar(fs, fs.nactvar - nvars).startpc = fs.pc;
};
const removevars = function(fs, tolevel) {
fs.ls.dyd.actvar.n -= fs.nactvar - tolevel;
while (fs.nactvar > tolevel)
getlocvar(fs, --fs.nactvar).endpc = fs.pc;
};
const searchupvalue = function(fs, name) {
let up = fs.f.upvalues;
for (let i = 0; i < fs.nups; i++) {
if (eqstr(up[i].name, name))
return i;
}
return -1; /* not found */
};
const newupvalue = function(fs, name, v) {
let f = fs.f;
checklimit(fs, fs.nups + 1, lfunc.MAXUPVAL, defs.to_luastring("upvalues", true));
f.upvalues[fs.nups] = {
instack: v.k === expkind.VLOCAL,
idx: v.u.info,
name: name
};
return fs.nups++;
};
const searchvar = function(fs, n) {
for (let i = fs.nactvar - 1; i >= 0; i--) {
if (eqstr(n, getlocvar(fs, i).varname))
return i;
}
return -1;
};
/*
** Mark block where variable at given level was defined
** (to emit close instructions later).
*/
const markupval = function(fs, level) {
let bl = fs.bl;
while (bl.nactvar > level)
bl = bl.previous;
bl.upval = 1;
};
/*
** Find variable with given name 'n'. If it is an upvalue, add this
** upvalue into all intermediate functions.
*/
const singlevaraux = function(fs, n, vr, base) {
if (fs === null) /* no more levels? */
init_exp(vr, expkind.VVOID, 0); /* default is global */
else {
let v = searchvar(fs, n); /* look up locals at current level */
if (v >= 0) { /* found? */
init_exp(vr, expkind.VLOCAL, v); /* variable is local */
if (!base)
markupval(fs, v); /* local will be used as an upval */
} else { /* not found as local at current level; try upvalues */
let idx = searchupvalue(fs, n); /* try existing upvalues */
if (idx < 0) { /* not found? */
singlevaraux(fs.prev, n, vr, 0); /* try upper levels */
if (vr.k === expkind.VVOID) /* not found? */
return; /* it is a global */
/* else was LOCAL or UPVAL */
idx = newupvalue(fs, n, vr); /* will be a new upvalue */
}
init_exp(vr, expkind.VUPVAL, idx); /* new or old upvalue */
}
}
};
const singlevar = function(ls, vr) {
let varname = str_checkname(ls);
let fs = ls.fs;
singlevaraux(fs, varname, vr, 1);
if (vr.k === expkind.VVOID) { /* global name? */
let key = new expdesc();
singlevaraux(fs, ls.envn, vr, 1); /* get environment variable */
assert(vr.k !== expkind.VVOID); /* this one must exist */
codestring(ls, key, varname); /* key is variable name */
lcode.luaK_indexed(fs, vr, key); /* env[varname] */
}
};
const adjust_assign = function(ls, nvars, nexps, e) {
let fs = ls.fs;
let extra = nvars - nexps;
if (hasmultret(e.k)) {
extra++; /* includes call itself */
if (extra < 0) extra = 0;
lcode.luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
if (extra > 1) lcode.luaK_reserveregs(fs, extra - 1);
} else {
if (e.k !== expkind.VVOID) lcode.luaK_exp2nextreg(fs, e); /* close last expression */
if (extra > 0) {
let reg = fs.freereg;
lcode.luaK_reserveregs(fs, extra);
lcode.luaK_nil(fs, reg, extra);
}
}
if (nexps > nvars)
ls.fs.freereg -= nexps - nvars; /* remove extra values */
};
const enterlevel = function(ls) {
let L = ls.L;
++L.nCcalls;
checklimit(ls.fs, L.nCcalls, llimit.LUAI_MAXCCALLS, defs.to_luastring("JS levels", true));
};
const leavelevel = function(ls) {
return ls.L.nCcalls--;
};
const closegoto = function(ls, g, label) {
let fs = ls.fs;
let gl = ls.dyd.gt;
let gt = gl.arr[g];
assert(eqstr(gt.name, label.name));
if (gt.nactvar < label.nactvar) {
let vname = getlocvar(fs, gt.nactvar).varname;
let msg = lobject.luaO_pushfstring(ls.L,
defs.to_luastring("<goto %s> at line %d jumps into the scope of local '%s'"),
gt.name.getstr(), gt.line, vname.getstr());
semerror(ls, msg);
}
lcode.luaK_patchlist(fs, gt.pc, label.pc);
/* remove goto from pending list */
for (let i = g; i < gl.n - 1; i++)
gl.arr[i] = gl.arr[i + 1];
gl.n--;
};
/*
** try to close a goto with existing labels; this solves backward jumps
*/
const findlabel = function(ls, g) {
let bl = ls.fs.bl;
let dyd = ls.dyd;
let gt = dyd.gt.arr[g];
/* check labels in current block for a match */
for (let i = bl.firstlabel; i < dyd.label.n; i++) {
let lb = dyd.label.arr[i];
if (eqstr(lb.name, gt.name)) { /* correct label? */
if (gt.nactvar > lb.nactvar && (bl.upval || dyd.label.n > bl.firstlabel))
lcode.luaK_patchclose(ls.fs, gt.pc, lb.nactvar);
closegoto(ls, g, lb); /* close it */
return true;
}
}
return false; /* label not found; cannot close goto */
};
const newlabelentry = function(ls, l, name, line, pc) {
let n = l.n;
l.arr[n] = new Labeldesc();
l.arr[n].name = name;
l.arr[n].line = line;
l.arr[n].nactvar = ls.fs.nactvar;
l.arr[n].pc = pc;
l.n = n + 1;
return n;
};
/*
** check whether new label 'lb' matches any pending gotos in current
** block; solves forward jumps
*/
const findgotos = function(ls, lb) {
let gl = ls.dyd.gt;
let i = ls.fs.bl.firstgoto;
while (i < gl.n) {
if (eqstr(gl.arr[i].name, lb.name))
closegoto(ls, i, lb);
else
i++;
}
};
/*
** export pending gotos to outer level, to check them against
** outer labels; if the block being exited has upvalues, and
** the goto exits the scope of any variable (which can be the
** upvalue), close those variables being exited.
*/
const movegotosout = function(fs, bl) {
let i = bl.firstgoto;
let gl = fs.ls.dyd.gt;
/* correct pending gotos to current block and try to close it
with visible labels */
while (i < gl.n) {
let gt = gl.arr[i];
if (gt.nactvar > bl.nactvar) {
if (bl.upval)
lcode.luaK_patchclose(fs, gt.pc, bl.nactvar);
gt.nactvar = bl.nactvar;
}
if (!findlabel(fs.ls, i))
i++; /* move to next one */
}
};
const enterblock = function(fs, bl, isloop) {
bl.isloop = isloop;
bl.nactvar = fs.nactvar;
bl.firstlabel = fs.ls.dyd.label.n;
bl.firstgoto = fs.ls.dyd.gt.n;
bl.upval = 0;
bl.previous = fs.bl;
fs.bl = bl;
assert(fs.freereg === fs.nactvar);
};
/*
** create a label named 'break' to resolve break statements
*/
const breaklabel = function(ls) {
let n = lstring.luaS_newliteral(ls.L, "break");
let l = newlabelentry(ls, ls.dyd.label, n, 0, ls.fs.pc);
findgotos(ls, ls.dyd.label.arr[l]);
};
/*
** generates an error for an undefined 'goto'; choose appropriate
** message when label name is a reserved word (which can only be 'break')
*/
const undefgoto = function(ls, gt) {
let msg = llex.isreserved(gt.name)
? "<%s> at line %d not inside a loop"
: "no visible label '%s' for <goto> at line %d";
msg = lobject.luaO_pushfstring(ls.L, defs.to_luastring(msg), gt.name.getstr(), gt.line);
semerror(ls, msg);
};
/*
** adds a new prototype into list of prototypes
*/
const addprototype = function(ls) {
let L = ls.L;
let clp = new Proto(L);
let fs = ls.fs;
let f = fs.f; /* prototype of current function */
f.p[fs.np++] = clp;
return clp;
};
/*
** codes instruction to create new closure in parent function.
*/
const codeclosure = function(ls, v) {
let fs = ls.fs.prev;
init_exp(v, expkind.VRELOCABLE, lcode.luaK_codeABx(fs, OpCodesI.OP_CLOSURE, 0, fs.np -1));
lcode.luaK_exp2nextreg(fs, v); /* fix it at the last register */
};
const open_func = function(ls, fs, bl) {
fs.prev = ls.fs; /* linked list of funcstates */
fs.ls = ls;
ls.fs = fs;
fs.pc = 0;
fs.lasttarget = 0;
fs.jpc = lcode.NO_JUMP;
fs.freereg = 0;
fs.nk = 0;
fs.np = 0;
fs.nups = 0;
fs.nlocvars = 0;
fs.nactvar = 0;
fs.firstlocal = ls.dyd.actvar.n;
fs.bl = null;
let f = new Proto(ls.L);
f = fs.f;
f.source = ls.source;
f.maxstacksize = 2; /* registers 0/1 are always valid */
enterblock(fs, bl, false);
};
const leaveblock = function(fs) {
let bl = fs.bl;
let ls = fs.ls;
if (bl.previous && bl.upval) {
/* create a 'jump to here' to close upvalues */
let j = lcode.luaK_jump(fs);
lcode.luaK_patchclose(fs, j , bl.nactvar);
lcode.luaK_patchtohere(fs, j);
}
if (bl.isloop)
breaklabel(ls); /* close pending breaks */
fs.bl = bl.previous;
removevars(fs, bl.nactvar);
assert(bl.nactvar === fs.nactvar);
fs.freereg = fs.nactvar; /* free registers */
ls.dyd.label.n = bl.firstlabel; /* remove local labels */
if (bl.previous) /* inner block? */
movegotosout(fs, bl); /* update pending gotos to outer block */
else if (bl.firstgoto < ls.dyd.gt.n) /* pending gotos in outer block? */
undefgoto(ls, ls.dyd.gt.arr[bl.firstgoto]); /* error */
};
const close_func = function(ls) {
let fs = ls.fs;
lcode.luaK_ret(fs, 0, 0); /* final return */
leaveblock(fs);
assert(fs.bl === null);
ls.fs = fs.prev;
};
/*============================================================*/
/* GRAMMAR RULES */
/*============================================================*/
const block_follow = function(ls, withuntil) {
switch (ls.t.token) {
case R.TK_ELSE: case R.TK_ELSEIF:
case R.TK_END: case R.TK_EOS:
return true;
case R.TK_UNTIL: return withuntil;
default: return false;
}
};
const statlist = function(ls) {
/* statlist -> { stat [';'] } */
while (!block_follow(ls, 1)) {
if (ls.t.token === R.TK_RETURN) {
statement(ls);
return; /* 'return' must be last statement */
}
statement(ls);
}
};
const fieldsel = function(ls, v) {
/* fieldsel -> ['.' | ':'] NAME */
let fs = ls.fs;
let key = new expdesc();
lcode.luaK_exp2anyregup(fs, v);
llex.luaX_next(ls); /* skip the dot or colon */
checkname(ls, key);
lcode.luaK_indexed(fs, v, key);
};
const yindex = function(ls, v) {
/* index -> '[' expr ']' */
llex.luaX_next(ls); /* skip the '[' */
expr(ls, v);
lcode.luaK_exp2val(ls.fs, v);
checknext(ls, char[']']);
};
/*
** {======================================================================
** Rules for Constructors
** =======================================================================
*/
class ConsControl {
constructor() {
this.v = new expdesc(); /* last list item read */
this.t = new expdesc(); /* table descriptor */
this.nh = NaN; /* total number of 'record' elements */
this.na = NaN; /* total number of array elements */
this.tostore = NaN; /* number of array elements pending to be stored */
}
}
const recfield = function(ls, cc) {
/* recfield -> (NAME | '['exp1']') = exp1 */
let fs = ls.fs;
let reg = ls.fs.freereg;
let key = new expdesc();
let val = new expdesc();
if (ls.t.token === R.TK_NAME) {
checklimit(fs, cc.nh, llimit.MAX_INT, defs.to_luastring("items in a constructor", true));
checkname(ls, key);
} else /* ls->t.token === '[' */
yindex(ls, key);
cc.nh++;
checknext(ls, char['=']);
let rkkey = lcode.luaK_exp2RK(fs, key);
expr(ls, val);
lcode.luaK_codeABC(fs, OpCodesI.OP_SETTABLE, cc.t.u.info, rkkey, lcode.luaK_exp2RK(fs, val));
fs.freereg = reg; /* free registers */
};
const closelistfield = function(fs, cc) {
if (cc.v.k === expkind.VVOID) return; /* there is no list item */
lcode.luaK_exp2nextreg(fs, cc.v);
cc.v.k = expkind.VVOID;
if (cc.tostore === lopcodes.LFIELDS_PER_FLUSH) {
lcode.luaK_setlist(fs, cc.t.u.info, cc.na, cc.tostore); /* flush */
cc.tostore = 0; /* no more items pending */
}
};
const lastlistfield = function(fs, cc) {
if (cc.tostore === 0) return;
if (hasmultret(cc.v.k)) {
lcode.luaK_setmultret(fs, cc.v);
lcode.luaK_setlist(fs, cc.t.u.info, cc.na, defs.LUA_MULTRET);
cc.na--; /* do not count last expression (unknown number of elements) */
} else {
if (cc.v.k !== expkind.VVOID)
lcode.luaK_exp2nextreg(fs, cc.v);
lcode.luaK_setlist(fs, cc.t.u.info, cc.na, cc.tostore);
}
};
const listfield = function(ls, cc) {
/* listfield -> exp */
expr(ls, cc.v);
checklimit(ls.fs, cc.na, llimit.MAX_INT, defs.to_luastring("items in a constructor", true));
cc.na++;
cc.tostore++;
};
const field = function(ls, cc) {
/* field -> listfield | recfield */
switch (ls.t.token) {
case R.TK_NAME: { /* may be 'listfield' or 'recfield' */
if (llex.luaX_lookahead(ls) !== char['=']) /* expression? */
listfield(ls, cc);
else
recfield(ls, cc);
break;
}
case char['[']: {
recfield(ls, cc);
break;
}
default: {
listfield(ls, cc);
break;
}
}
};
const constructor = function(ls, t) {
/* constructor -> '{' [ field { sep field } [sep] ] '}'
sep -> ',' | ';' */
let fs = ls.fs;
let line = ls.linenumber;
let pc = lcode.luaK_codeABC(fs, OpCodesI.OP_NEWTABLE, 0, 0, 0);
let cc = new ConsControl();
cc.na = cc.nh = cc.tostore = 0;
cc.t = t;
init_exp(t, expkind.VRELOCABLE, pc);
init_exp(cc.v, expkind.VVOID, 0); /* no value (yet) */
lcode.luaK_exp2nextreg(ls.fs, t); /* fix it at stack top */
checknext(ls, char['{']);
do {
assert(cc.v.k === expkind.VVOID || cc.tostore > 0);
if (ls.t.token === char['}']) break;
closelistfield(fs, cc);
field(ls, cc);
} while (testnext(ls, char[',']) || testnext(ls, char[';']));
check_match(ls, char['}'], char['{'], line);
lastlistfield(fs, cc);
lopcodes.SETARG_B(fs.f.code[pc], lobject.luaO_int2fb(cc.na)); /* set initial array size */
lopcodes.SETARG_C(fs.f.code[pc], lobject.luaO_int2fb(cc.nh)); /* set initial table size */
};
/* }====================================================================== */
const parlist = function(ls) {
/* parlist -> [ param { ',' param } ] */
let fs = ls.fs;
let f = fs.f;
let nparams = 0;
f.is_vararg = false;
if (ls.t.token !== char[')']) { /* is 'parlist' not empty? */
do {
switch (ls.t.token) {
case R.TK_NAME: { /* param -> NAME */
new_localvar(ls, str_checkname(ls));
nparams++;
break;
}
case R.TK_DOTS: { /* param -> '...' */
llex.luaX_next(ls);
f.is_vararg = true; /* declared vararg */
break;
}
default: llex.luaX_syntaxerror(ls, defs.to_luastring("<name> or '...' expected", true));
}
} while(!f.is_vararg && testnext(ls, char[',']));
}
adjustlocalvars(ls, nparams);
f.numparams = fs.nactvar;
lcode.luaK_reserveregs(fs, fs.nactvar); /* reserve register for parameters */
};
const body = function(ls, e, ismethod, line) {
/* body -> '(' parlist ')' block END */
let new_fs = new FuncState();
let bl = new BlockCnt();
new_fs.f = addprototype(ls);
new_fs.f.linedefined = line;
open_func(ls, new_fs, bl);
checknext(ls, char['(']);
if (ismethod) {
new_localvarliteral(ls, "self"); /* create 'self' parameter */
adjustlocalvars(ls, 1);
}
parlist(ls);
checknext(ls, char[')']);
statlist(ls);
new_fs.f.lastlinedefined = ls.linenumber;
check_match(ls, R.TK_END, R.TK_FUNCTION, line);
codeclosure(ls, e);
close_func(ls);
};
const explist = function(ls, v) {
/* explist -> expr { ',' expr } */
let n = 1; /* at least one expression */
expr(ls, v);
while (testnext(ls, char[','])) {
lcode.luaK_exp2nextreg(ls.fs, v);
expr(ls, v);
n++;
}
return n;
};
const funcargs = function(ls, f, line) {
let fs = ls.fs;
let args = new expdesc();
switch (ls.t.token) {
case char['(']: { /* funcargs -> '(' [ explist ] ')' */
llex.luaX_next(ls);
if (ls.t.token === char[')']) /* arg list is empty? */
args.k = expkind.VVOID;
else {
explist(ls, args);
lcode.luaK_setmultret(fs, args);
}
check_match(ls, char[')'], char['('], line);
break;
}
case char['{']: { /* funcargs -> constructor */
constructor(ls, args);
break;
}
case R.TK_STRING: { /* funcargs -> STRING */
codestring(ls, args, ls.t.seminfo.ts);
llex.luaX_next(ls); /* must use 'seminfo' before 'next' */
break;
}
default: {
llex.luaX_syntaxerror(ls, defs.to_luastring("function arguments expected", true));
}
}
assert(f.k === expkind.VNONRELOC);
let nparams;
let base = f.u.info; /* base register for call */
if (hasmultret(args.k))
nparams = defs.LUA_MULTRET; /* open call */
else {
if (args.k !== expkind.VVOID)
lcode.luaK_exp2nextreg(fs, args); /* close last argument */
nparams = fs.freereg - (base+1);
}
init_exp(f, expkind.VCALL, lcode.luaK_codeABC(fs, OpCodesI.OP_CALL, base, nparams+1, 2));
lcode.luaK_fixline(fs, line);
fs.freereg = base + 1; /* call remove function and arguments and leaves (unless changed) one result */
};
/*
** {======================================================================
** Expression parsing
** =======================================================================
*/
const primaryexp = function(ls, v) {
/* primaryexp -> NAME | '(' expr ')' */
switch (ls.t.token) {
case char['(']: {
let line = ls.linenumber;
llex.luaX_next(ls);
expr(ls, v);
check_match(ls, char[')'], char['('], line);
lcode.luaK_dischargevars(ls.fs, v);
return;
}
case R.TK_NAME: {
singlevar(ls, v);
return;
}
default: {
llex.luaX_syntaxerror(ls, defs.to_luastring("unexpected symbol", true));
}
}
};
const suffixedexp = function(ls, v) {
/* suffixedexp ->
primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
let fs = ls.fs;
let line = ls.linenumber;
primaryexp(ls, v);
for (;;) {
switch (ls.t.token) {
case char['.']: { /* fieldsel */
fieldsel(ls, v);
break;
}
case char['[']: { /* '[' exp1 ']' */
let key = new expdesc();
lcode.luaK_exp2anyregup(fs, v);
yindex(ls, key);
lcode.luaK_indexed(fs, v, key);
break;
}
case char[':']: { /* ':' NAME funcargs */
let key = new expdesc();
llex.luaX_next(ls);
checkname(ls, key);
lcode.luaK_self(fs, v, key);
funcargs(ls, v, line);
break;
}
case char['(']: case R.TK_STRING: case char['{']: { /* funcargs */
lcode.luaK_exp2nextreg(fs, v);
funcargs(ls, v, line);
break;
}
default: return;
}
}
};
const simpleexp = function(ls, v) {
/* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... |
constructor | FUNCTION body | suffixedexp */
switch (ls.t.token) {
case R.TK_FLT: {
init_exp(v, expkind.VKFLT, 0);
v.u.nval = ls.t.seminfo.r;
break;
}
case R.TK_INT: {
init_exp(v, expkind.VKINT, 0);
v.u.ival = ls.t.seminfo.i;
break;
}
case R.TK_STRING: {
codestring(ls, v, ls.t.seminfo.ts);
break;
}
case R.TK_NIL: {
init_exp(v, expkind.VNIL, 0);
break;
}
case R.TK_TRUE: {
init_exp(v, expkind.VTRUE, 0);
break;
}
case R.TK_FALSE: {
init_exp(v, expkind.VFALSE, 0);
break;
}
case R.TK_DOTS: { /* vararg */
let fs = ls.fs;
check_condition(ls, fs.f.is_vararg, defs.to_luastring("cannot use '...' outside a vararg function", true));
init_exp(v, expkind.VVARARG, lcode.luaK_codeABC(fs, OpCodesI.OP_VARARG, 0, 1, 0));
break;
}
case char['{']: { /* constructor */
constructor(ls, v);
return;
}
case R.TK_FUNCTION: {
llex.luaX_next(ls);
body(ls, v, 0, ls.linenumber);
return;
}
default: {
suffixedexp(ls, v);
return;
}
}
llex.luaX_next(ls);
};
const getunopr = function(op) {
switch (op) {
case R.TK_NOT: return UnOpr.OPR_NOT;
case char['-']: return UnOpr.OPR_MINUS;
case char['~']: return UnOpr.OPR_BNOT;
case char['#']: return UnOpr.OPR_LEN;
default: return UnOpr.OPR_NOUNOPR;
}
};
const getbinopr = function(op) {
switch (op) {
case char['+']: return BinOpr.OPR_ADD;
case char['-']: return BinOpr.OPR_SUB;
case char['*']: return BinOpr.OPR_MUL;
case char['%']: return BinOpr.OPR_MOD;
case char['^']: return BinOpr.OPR_POW;
case char['/']: return BinOpr.OPR_DIV;
case R.TK_IDIV: return BinOpr.OPR_IDIV;
case char['&']: return BinOpr.OPR_BAND;
case char['|']: return BinOpr.OPR_BOR;
case char['~']: return BinOpr.OPR_BXOR;
case R.TK_SHL: return BinOpr.OPR_SHL;
case R.TK_SHR: return BinOpr.OPR_SHR;
case R.TK_CONCAT: return BinOpr.OPR_CONCAT;
case R.TK_NE: return BinOpr.OPR_NE;
case R.TK_EQ: return BinOpr.OPR_EQ;
case char['<']: return BinOpr.OPR_LT;
case R.TK_LE: return BinOpr.OPR_LE;
case char['>']: return BinOpr.OPR_GT;
case R.TK_GE: return BinOpr.OPR_GE;
case R.TK_AND: return BinOpr.OPR_AND;
case R.TK_OR: return BinOpr.OPR_OR;
default: return BinOpr.OPR_NOBINOPR;
}
};
const priority = [ /* ORDER OPR */
{left: 10, right: 10}, {left: 10, right: 10}, /* '+' '-' */
{left: 11, right: 11}, {left: 11, right: 11}, /* '*' '%' */
{left: 14, right: 13}, /* '^' (right associative) */
{left: 11, right: 11}, {left: 11, right: 11}, /* '/' '//' */
{left: 6, right: 6}, {left: 4, right: 4}, {left: 5, right: 5}, /* '&' '|' '~' */
{left: 7, right: 7}, {left: 7, right: 7}, /* '<<' '>>' */
{left: 9, right: 8}, /* '..' (right associative) */
{left: 3, right: 3}, {left: 3, right: 3}, {left: 3, right: 3}, /* ==, <, <= */
{left: 3, right: 3}, {left: 3, right: 3}, {left: 3, right: 3}, /* ~=, >, >= */
{left: 2, right: 2}, {left: 1, right: 1} /* and, or */
];
const UNARY_PRIORITY = 12;
/*
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
** where 'binop' is any binary operator with a priority higher than 'limit'
*/
const subexpr = function(ls, v, limit) {
enterlevel(ls);
let uop = getunopr(ls.t.token);
if (uop !== UnOpr.OPR_NOUNOPR) {
let line = ls.linenumber;
llex.luaX_next(ls);
subexpr(ls, v, UNARY_PRIORITY);
lcode.luaK_prefix(ls.fs, uop, v, line);
} else
simpleexp(ls, v);
/* expand while operators have priorities higher than 'limit' */
let op = getbinopr(ls.t.token);
while (op !== BinOpr.OPR_NOBINOPR && priority[op].left > limit) {
let v2 = new expdesc();
let line = ls.linenumber;
llex.luaX_next(ls);
lcode.luaK_infix(ls.fs, op, v);
/* read sub-expression with higher priority */
let nextop = subexpr(ls, v2, priority[op].right);
lcode.luaK_posfix(ls.fs, op, v, v2, line);
op = nextop;
}
leavelevel(ls);
return op; /* return first untreated operator */
};
const expr = function(ls, v) {
subexpr(ls, v, 0);
};
/* }==================================================================== */
/*
** {======================================================================
** Rules for Statements
** =======================================================================
*/
const block = function(ls) {
/* block -> statlist */
let fs = ls.fs;
let bl = new BlockCnt();
enterblock(fs, bl, 0);
statlist(ls);
leaveblock(fs);
};
/*
** structure to chain all variables in the left-hand side of an
** assignment
*/
class LHS_assign {
constructor() {
this.prev = null;
this.v = new expdesc(); /* variable (global, local, upvalue, or indexed) */
}
}
/*
** check whether, in an assignment to an upvalue/local variable, the
** upvalue/local variable is begin used in a previous assignment to a
** table. If so, save original upvalue/local value in a safe place and
** use this safe copy in the previous assignment.
*/
const check_conflict = function(ls, lh, v) {
let fs = ls.fs;
let extra = fs.freereg; /* eventual position to save local variable */
let conflict = false;
for (; lh; lh = lh.prev) { /* check all previous assignments */
if (lh.v.k === expkind.VINDEXED) { /* assigning to a table? */
/* table is the upvalue/local being assigned now? */
if (lh.v.u.ind.vt === v.k && lh.v.u.ind.t === v.u.info) {
conflict = true;
lh.v.u.ind.vt = expkind.VLOCAL;
lh.v.u.ind.t = extra; /* previous assignment will use safe copy */
}
/* index is the local being assigned? (index cannot be upvalue) */
if (v.k === expkind.VLOCAL && lh.v.u.ind.idx === v.u.info) {
conflict = true;
lh.v.u.ind.idx = extra; /* previous assignment will use safe copy */
}
}
}
if (conflict) {
/* copy upvalue/local value to a temporary (in position 'extra') */
let op = v.k === expkind.VLOCAL ? OpCodesI.OP_MOVE : OpCodesI.OP_GETUPVAL;
lcode.luaK_codeABC(fs, op, extra, v.u.info, 0);
lcode.luaK_reserveregs(fs, 1);
}
};
const assignment = function(ls, lh, nvars) {
let e = new expdesc();
check_condition(ls, vkisvar(lh.v.k), defs.to_luastring("syntax error", true));
if (testnext(ls, char[','])) { /* assignment -> ',' suffixedexp assignment */
let nv = new LHS_assign();
nv.prev = lh;
suffixedexp(ls, nv.v);
if (nv.v.k !== expkind.VINDEXED)
check_conflict(ls, lh, nv.v);
checklimit(ls.fs, nvars + ls.L.nCcalls, llimit.LUAI_MAXCCALLS, defs.to_luastring("JS levels", true));
assignment(ls, nv, nvars + 1);
} else { /* assignment -> '=' explist */
checknext(ls, char['=']);
let nexps = explist(ls, e);
if (nexps !== nvars)
adjust_assign(ls, nvars, nexps, e);
else {
lcode.luaK_setoneret(ls.fs, e); /* close last expression */
lcode.luaK_storevar(ls.fs, lh.v, e);
return; /* avoid default */
}
}
init_exp(e, expkind.VNONRELOC, ls.fs.freereg-1); /* default assignment */
lcode.luaK_storevar(ls.fs, lh.v, e);
};
const cond = function(ls) {
/* cond -> exp */
let v = new expdesc();
expr(ls, v); /* read condition */
if (v.k === expkind.VNIL) v.k = expkind.VFALSE; /* 'falses' are all equal here */
lcode.luaK_goiftrue(ls.fs, v);
return v.f;
};
const gotostat = function(ls, pc) {
let line = ls.linenumber;
let label;
if (testnext(ls, R.TK_GOTO))
label = str_checkname(ls);
else {
llex.luaX_next(ls); /* skip break */
label = lstring.luaS_newliteral(ls.L, "break");
}
let g = newlabelentry(ls, ls.dyd.gt, label, line, pc);
findlabel(ls, g); /* close it if label already defined */
};
/* check for repeated labels on the same block */
const checkrepeated = function(fs, ll, label) {
for (let i = fs.bl.firstlabel; i < ll.n; i++) {
if (eqstr(label, ll.arr[i].name)) {
let msg = lobject.luaO_pushfstring(fs.ls.L,
defs.to_luastring("label '%s' already defined on line %d", true),
label.getstr(), ll.arr[i].line);
semerror(fs.ls, msg);
}
}
};
/* skip no-op statements */
const skipnoopstat = function(ls) {
while (ls.t.token === char[';'] || ls.t.token === R.TK_DBCOLON)
statement(ls);
};
const labelstat = function(ls, label, line) {
/* label -> '::' NAME '::' */
let fs = ls.fs;
let ll = ls.dyd.label;
let l; /* index of new label being created */
checkrepeated(fs, ll, label); /* check for repeated labels */
checknext(ls, R.TK_DBCOLON); /* skip double colon */
/* create new entry for this label */
l = newlabelentry(ls, ll, label, line, lcode.luaK_getlabel(fs));
skipnoopstat(ls); /* skip other no-op statements */
if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
/* assume that locals are already out of scope */
ll.arr[l].nactvar = fs.bl.nactvar;
}
findgotos(ls, ll.arr[l]);
};
const whilestat = function(ls, line) {
/* whilestat -> WHILE cond DO block END */
let fs = ls.fs;
let bl = new BlockCnt();
llex.luaX_next(ls); /* skip WHILE */
let whileinit = lcode.luaK_getlabel(fs);
let condexit = cond(ls);
enterblock(fs, bl, 1);
checknext(ls, R.TK_DO);
block(ls);
lcode.luaK_jumpto(fs, whileinit);
check_match(ls, R.TK_END, R.TK_WHILE, line);
leaveblock(fs);
lcode.luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
};
const repeatstat = function(ls, line) {
/* repeatstat -> REPEAT block UNTIL cond */
let fs = ls.fs;
let repeat_init = lcode.luaK_getlabel(fs);
let bl1 = new BlockCnt();
let bl2 = new BlockCnt();
enterblock(fs, bl1, 1); /* loop block */
enterblock(fs, bl2, 0); /* scope block */
llex.luaX_next(ls); /* skip REPEAT */
statlist(ls);
check_match(ls, R.TK_UNTIL, R.TK_REPEAT, line);
let condexit = cond(ls); /* read condition (inside scope block) */
if (bl2.upval) /* upvalues? */
lcode.luaK_patchclose(fs, condexit, bl2.nactvar);
leaveblock(fs); /* finish scope */
lcode.luaK_patchlist(fs, condexit, repeat_init); /* close the loop */
leaveblock(fs); /* finish loop */
};
const exp1 = function(ls) {
let e = new expdesc();
expr(ls, e);
lcode.luaK_exp2nextreg(ls.fs, e);
assert(e.k === expkind.VNONRELOC);
let reg = e.u.info;
return reg;
};
const forbody = function(ls, base, line, nvars, isnum) {
/* forbody -> DO block */
let bl = new BlockCnt();
let fs = ls.fs;
let endfor;
adjustlocalvars(ls, 3); /* control variables */
checknext(ls, R.TK_DO);
let prep = isnum ? lcode.luaK_codeAsBx(fs, OpCodesI.OP_FORPREP, base, lcode.NO_JUMP) : lcode.luaK_jump(fs);
enterblock(fs, bl, 0); /* scope for declared variables */
adjustlocalvars(ls, nvars);
lcode.luaK_reserveregs(fs, nvars);
block(ls);
leaveblock(fs); /* end of scope for declared variables */
lcode.luaK_patchtohere(fs, prep);
if (isnum) /* end of scope for declared variables */
endfor = lcode.luaK_codeAsBx(fs, OpCodesI.OP_FORLOOP, base, lcode.NO_JUMP);
else { /* generic for */
lcode.luaK_codeABC(fs, OpCodesI.OP_TFORCALL, base, 0, nvars);
lcode.luaK_fixline(fs, line);
endfor = lcode.luaK_codeAsBx(fs, OpCodesI.OP_TFORLOOP, base + 2, lcode.NO_JUMP);
}
lcode.luaK_patchlist(fs, endfor, prep + 1);
lcode.luaK_fixline(fs, line);
};
const fornum = function(ls, varname, line) {
/* fornum -> NAME = exp1,exp1[,exp1] forbody */
let fs = ls.fs;
let base = fs.freereg;
new_localvarliteral(ls, "(for index)");
new_localvarliteral(ls, "(for limit)");
new_localvarliteral(ls, "(for step)");
new_localvar(ls, varname);
checknext(ls, char['=']);
exp1(ls); /* initial value */
checknext(ls, char[',']);
exp1(ls); /* limit */
if (testnext(ls, char[',']))
exp1(ls); /* optional step */
else { /* default step = 1 */
lcode.luaK_codek(fs, fs.freereg, lcode.luaK_intK(fs, 1));
lcode.luaK_reserveregs(fs, 1);
}
forbody(ls, base, line, 1, 1);
};
const forlist = function(ls, indexname) {
/* forlist -> NAME {,NAME} IN explist forbody */
let fs = ls.fs;
let e = new expdesc();
let nvars = 4; /* gen, state, control, plus at least one declared var */
let base = fs.freereg;
/* create control variables */
new_localvarliteral(ls, "(for generator)");
new_localvarliteral(ls, "(for state)");
new_localvarliteral(ls, "(for control)");
/* create declared variables */
new_localvar(ls, indexname);
while (testnext(ls, char[','])) {
new_localvar(ls, str_checkname(ls));
nvars++;
}
checknext(ls, R.TK_IN);
let line = ls.linenumber;
adjust_assign(ls, 3, explist(ls, e), e);
lcode.luaK_checkstack(fs, 3); /* extra space to call generator */
forbody(ls, base, line, nvars - 3, 0);
};
const forstat = function(ls, line) {
/* forstat -> FOR (fornum | forlist) END */
let fs = ls.fs;
let bl = new BlockCnt();
enterblock(fs, bl, 1); /* scope for loop and control variables */
llex.luaX_next(ls); /* skip 'for' */
let varname = str_checkname(ls); /* first variable name */
switch (ls.t.token) {
case char['=']: fornum(ls, varname, line); break;
case char[',']: case R.TK_IN: forlist(ls, varname); break;
default: llex.luaX_syntaxerror(ls, defs.to_luastring("'=' or 'in' expected", true));
}
check_match(ls, R.TK_END, R.TK_FOR, line);
leaveblock(fs); /* loop scope ('break' jumps to this point) */
};
const test_then_block = function(ls, escapelist) {
/* test_then_block -> [IF | ELSEIF] cond THEN block */
let bl = new BlockCnt();
let fs = ls.fs;
let v = new expdesc();
let jf; /* instruction to skip 'then' code (if condition is false) */
llex.luaX_next(ls); /* skip IF or ELSEIF */
expr(ls, v); /* read condition */
checknext(ls, R.TK_THEN);
if (ls.t.token === R.TK_GOTO || ls.t.token === R.TK_BREAK) {
lcode.luaK_goiffalse(ls.fs, v); /* will jump to label if condition is true */
enterblock(fs, bl, false); /* must enter block before 'goto' */
gotostat(ls, v.t); /* handle goto/break */
while (testnext(ls, char[';'])) {} /* skip colons */
if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
leaveblock(fs);
return escapelist; /* and that is it */
} else /* must skip over 'then' part if condition is false */
jf = lcode.luaK_jump(fs);
} else { /* regular case (not goto/break) */
lcode.luaK_goiftrue(ls.fs, v); /* skip over block if condition is false */
enterblock(fs, bl, false);
jf = v.f;
}
statlist(ls); /* 'then' part */
leaveblock(fs);
if (ls.t.token === R.TK_ELSE || ls.t.token === R.TK_ELSEIF) /* followed by 'else'/'elseif'? */
escapelist = lcode.luaK_concat(fs, escapelist, lcode.luaK_jump(fs)); /* must jump over it */
lcode.luaK_patchtohere(fs, jf);
return escapelist;
};
const ifstat = function(ls, line) {
/* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
let fs = ls.fs;
let escapelist = lcode.NO_JUMP; /* exit list for finished parts */
escapelist = test_then_block(ls, escapelist); /* IF cond THEN block */
while (ls.t.token === R.TK_ELSEIF)
escapelist = test_then_block(ls, escapelist); /* ELSEIF cond THEN block */
if (testnext(ls, R.TK_ELSE))
block(ls); /* 'else' part */
check_match(ls, R.TK_END, R.TK_IF, line);
lcode.luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */
};
const localfunc = function(ls) {
let b = new expdesc();
let fs = ls.fs;
new_localvar(ls, str_checkname(ls)); /* new local variable */
adjustlocalvars(ls, 1); /* enter its scope */
body(ls, b, 0, ls.linenumber); /* function created in next register */
/* debug information will only see the variable after this point! */
getlocvar(fs, b.u.info).startpc = fs.pc;
};
const localstat = function(ls) {
/* stat -> LOCAL NAME {',' NAME} ['=' explist] */
let nvars = 0;
let nexps;
let e = new expdesc();
do {
new_localvar(ls, str_checkname(ls));
nvars++;
} while (testnext(ls, char[',']));
if (testnext(ls, char['=']))
nexps = explist(ls, e);
else {
e.k = expkind.VVOID;
nexps = 0;
}
adjust_assign(ls, nvars, nexps, e);
adjustlocalvars(ls, nvars);
};
const funcname = function(ls, v) {
/* funcname -> NAME {fieldsel} [':' NAME] */
let ismethod = 0;
singlevar(ls, v);
while (ls.t.token === char['.'])
fieldsel(ls, v);
if (ls.t.token === char[':']) {
ismethod = 1;
fieldsel(ls, v);
}
return ismethod;
};
const funcstat = function(ls, line) {
/* funcstat -> FUNCTION funcname body */
let v = new expdesc();
let b = new expdesc();
llex.luaX_next(ls); /* skip FUNCTION */
let ismethod = funcname(ls, v);
body(ls, b, ismethod, line);
lcode.luaK_storevar(ls.fs, v, b);
lcode.luaK_fixline(ls.fs, line); /* definition "happens" in the first line */
};
const exprstat= function(ls) {
/* stat -> func | assignment */
let fs = ls.fs;
let v = new LHS_assign();
suffixedexp(ls, v.v);
if (ls.t.token === char['='] || ls.t.token === char[',']) { /* stat . assignment ? */
v.prev = null;
assignment(ls, v, 1);
}
else { /* stat -> func */
check_condition(ls, v.v.k === expkind.VCALL, defs.to_luastring("syntax error", true));
lopcodes.SETARG_C(lcode.getinstruction(fs, v.v), 1); /* call statement uses no results */
}
};
const retstat = function(ls) {
/* stat -> RETURN [explist] [';'] */
let fs = ls.fs;
let e = new expdesc();
let first, nret; /* registers with returned values */
if (block_follow(ls, 1) || ls.t.token === char[';'])
first = nret = 0; /* return no values */
else {
nret = explist(ls, e); /* optional return values */
if (hasmultret(e.k)) {
lcode.luaK_setmultret(fs, e);
if (e.k === expkind.VCALL && nret === 1) { /* tail call? */
lopcodes.SET_OPCODE(lcode.getinstruction(fs, e), OpCodesI.OP_TAILCALL);
assert(lcode.getinstruction(fs, e).A === fs.nactvar);
}
first = fs.nactvar;
nret = defs.LUA_MULTRET; /* return all values */
} else {
if (nret === 1) /* only one single value? */
first = lcode.luaK_exp2anyreg(fs, e);
else {
lcode.luaK_exp2nextreg(fs, e); /* values must go to the stack */
first = fs.nactvar; /* return all active values */
assert(nret === fs.freereg - first);
}
}
}
lcode.luaK_ret(fs, first, nret);
testnext(ls, char[';']); /* skip optional semicolon */
};
const statement = function(ls) {
let line = ls.linenumber; /* may be needed for error messages */
enterlevel(ls);
switch(ls.t.token) {
case char[';']: { /* stat -> ';' (empty statement) */
llex.luaX_next(ls); /* skip ';' */
break;
}
case R.TK_IF: { /* stat -> ifstat */
ifstat(ls, line);
break;
}
case R.TK_WHILE: { /* stat -> whilestat */
whilestat(ls, line);
break;
}
case R.TK_DO: { /* stat -> DO block END */
llex.luaX_next(ls); /* skip DO */
block(ls);
check_match(ls, R.TK_END, R.TK_DO, line);
break;
}
case R.TK_FOR: { /* stat -> forstat */
forstat(ls, line);
break;
}
case R.TK_REPEAT: { /* stat -> repeatstat */
repeatstat(ls, line);
break;
}
case R.TK_FUNCTION: { /* stat -> funcstat */
funcstat(ls, line);
break;
}
case R.TK_LOCAL: { /* stat -> localstat */
llex.luaX_next(ls); /* skip LOCAL */
if (testnext(ls, R.TK_FUNCTION)) /* local function? */
localfunc(ls);
else
localstat(ls);
break;
}
case R.TK_DBCOLON: { /* stat -> label */
llex.luaX_next(ls); /* skip double colon */
labelstat(ls, str_checkname(ls), line);
break;
}
case R.TK_RETURN: { /* skip double colon */
llex.luaX_next(ls); /* skip RETURN */
retstat(ls);
break;
}
case R.TK_BREAK: /* stat -> breakstat */
case R.TK_GOTO: { /* stat -> 'goto' NAME */
gotostat(ls, lcode.luaK_jump(ls.fs));
break;
}
default: { /* stat -> func | assignment */
exprstat(ls);
break;
}
}
assert(ls.fs.f.maxstacksize >= ls.fs.freereg && ls.fs.freereg >= ls.fs.nactvar);
ls.fs.freereg = ls.fs.nactvar; /* free registers */
leavelevel(ls);
};
/*
** compiles the main function, which is a regular vararg function with an
** upvalue named LUA_ENV
*/
const mainfunc = function(ls, fs) {
let bl = new BlockCnt();
let v = new expdesc();
open_func(ls, fs, bl);
fs.f.is_vararg = true; /* main function is always declared vararg */
init_exp(v, expkind.VLOCAL, 0); /* create and... */
newupvalue(fs, ls.envn, v); /* ...set environment upvalue */
llex.luaX_next(ls); /* read first token */
statlist(ls); /* parse main body */
check(ls, R.TK_EOS);
close_func(ls);
};
const luaY_parser = function(L, z, buff, dyd, name, firstchar) {
let lexstate = new llex.LexState();
let funcstate = new FuncState();
let cl = lfunc.luaF_newLclosure(L, 1); /* create main closure */
ldo.luaD_inctop(L);
L.stack[L.top-1].setclLvalue(cl);
lexstate.h = ltable.luaH_new(L); /* create table for scanner */
ldo.luaD_inctop(L);
L.stack[L.top-1].sethvalue(lexstate.h);
funcstate.f = cl.p = new Proto(L);
funcstate.f.source = lstring.luaS_new(L, name);
lexstate.buff = buff;
lexstate.dyd = dyd;
dyd.actvar.n = dyd.gt.n = dyd.label.n = 0;
llex.luaX_setinput(L, lexstate, z, funcstate.f.source, firstchar);
mainfunc(lexstate, funcstate);
assert(!funcstate.prev && funcstate.nups === 1 && !lexstate.fs);
/* all scopes should be correctly finished */
assert(dyd.actvar.n === 0 && dyd.gt.n === 0 && dyd.label.n === 0);
delete L.stack[--L.top]; /* remove scanner's table */
return cl; /* closure is on the stack, too */
};
module.exports.Dyndata = Dyndata;
module.exports.expkind = expkind;
module.exports.expdesc = expdesc;
module.exports.luaY_parser = luaY_parser;
module.exports.vkisinreg = vkisinreg;
/***/ }),
/* 42 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const defs = __webpack_require__(1);
const ldebug = __webpack_require__(19);
const ldo = __webpack_require__(12);
const ljstype = __webpack_require__(40);
const lobject = __webpack_require__(5);
const lstring = __webpack_require__(15);
const ltable = __webpack_require__(14);
const llimit = __webpack_require__(8);
const lzio = __webpack_require__(35);
const TS = defs.thread_status;
const char = defs.char;
const FIRST_RESERVED = 257;
const RESERVED = {
/* terminal symbols denoted by reserved words */
TK_AND: FIRST_RESERVED,
TK_BREAK: FIRST_RESERVED + 1,
TK_DO: FIRST_RESERVED + 2,
TK_ELSE: FIRST_RESERVED + 3,
TK_ELSEIF: FIRST_RESERVED + 4,
TK_END: FIRST_RESERVED + 5,
TK_FALSE: FIRST_RESERVED + 6,
TK_FOR: FIRST_RESERVED + 7,
TK_FUNCTION: FIRST_RESERVED + 8,
TK_GOTO: FIRST_RESERVED + 9,
TK_IF: FIRST_RESERVED + 10,
TK_IN: FIRST_RESERVED + 11,
TK_LOCAL: FIRST_RESERVED + 12,
TK_NIL: FIRST_RESERVED + 13,
TK_NOT: FIRST_RESERVED + 14,
TK_OR: FIRST_RESERVED + 15,
TK_REPEAT: FIRST_RESERVED + 16,
TK_RETURN: FIRST_RESERVED + 17,
TK_THEN: FIRST_RESERVED + 18,
TK_TRUE: FIRST_RESERVED + 19,
TK_UNTIL: FIRST_RESERVED + 20,
TK_WHILE: FIRST_RESERVED + 21,
/* other terminal symbols */
TK_IDIV: FIRST_RESERVED + 22,
TK_CONCAT: FIRST_RESERVED + 23,
TK_DOTS: FIRST_RESERVED + 24,
TK_EQ: FIRST_RESERVED + 25,
TK_GE: FIRST_RESERVED + 26,
TK_LE: FIRST_RESERVED + 27,
TK_NE: FIRST_RESERVED + 28,
TK_SHL: FIRST_RESERVED + 29,
TK_SHR: FIRST_RESERVED + 30,
TK_DBCOLON: FIRST_RESERVED + 31,
TK_EOS: FIRST_RESERVED + 32,
TK_FLT: FIRST_RESERVED + 33,
TK_INT: FIRST_RESERVED + 34,
TK_NAME: FIRST_RESERVED + 35,
TK_STRING: FIRST_RESERVED + 36
};
const R = RESERVED;
const luaX_tokens = [
"and", "break", "do", "else", "elseif",
"end", "false", "for", "function", "goto", "if",
"in", "local", "nil", "not", "or", "repeat",
"return", "then", "true", "until", "while",
"//", "..", "...", "==", ">=", "<=", "~=",
"<<", ">>", "::", "<eof>",
"<number>", "<integer>", "<name>", "<string>"
];
class SemInfo {
constructor() {
this.r = NaN;
this.i = NaN;
this.ts = null;
}
}
class Token {
constructor() {
this.token = NaN;
this.seminfo = new SemInfo();
}
}
/* state of the lexer plus state of the parser when shared by all
functions */
class LexState {
constructor() {
this.current = NaN; /* current character (charint) */
this.linenumber = NaN; /* input line counter */
this.lastline = NaN; /* line of last token 'consumed' */
this.t = new Token(); /* current token */
this.lookahead = new Token(); /* look ahead token */
this.fs = null; /* current function (parser) */
this.L = null;
this.z = null; /* input stream */
this.buff = null; /* buffer for tokens */
this.h = null; /* to reuse strings */
this.dyd = null; /* dynamic structures used by the parser */
this.source = null; /* current source name */
this.envn = null; /* environment variable name */
}
}
const save = function(ls, c) {
let b = ls.buff;
if (b.n + 1 > b.buffer.length) {
if (b.buffer.length >= llimit.MAX_INT/2)
lexerror(ls, defs.to_luastring("lexical element too long", true), 0);
}
b.buffer[b.n++] = c < 0 ? 255 + c + 1 : c;
};
const luaX_token2str = function(ls, token) {
if (token < FIRST_RESERVED) { /* single-byte symbols? */
return lobject.luaO_pushfstring(ls.L, defs.to_luastring("'%c'", true), token);
} else {
let s = luaX_tokens[token - FIRST_RESERVED];
if (token < R.TK_EOS) /* fixed format (symbols and reserved words)? */
return lobject.luaO_pushfstring(ls.L, defs.to_luastring("'%s'", true), defs.to_luastring(s));
else /* names, strings, and numerals */
return defs.to_luastring(s);
}
};
const currIsNewline = function(ls) {
return ls.current === char['\n'] || ls.current === char['\r'];
};
const next = function(ls) {
ls.current = ls.z.zgetc();
};
const save_and_next = function(ls) {
save(ls, ls.current);
next(ls);
};
/*
** creates a new string and anchors it in scanner's table so that
** it will not be collected until the end of the compilation
** (by that time it should be anchored somewhere)
*/
const luaX_newstring = function(ls, str) {
let L = ls.L;
let ts = lstring.luaS_new(L, str);
let o = ltable.luaH_set(L, ls.h, new lobject.TValue(defs.CT.LUA_TLNGSTR, ts));
if (o.ttisnil()) { /* not in use yet? */
o.setbvalue(true);
} else { /* string already present */
/* HACK: Workaround lack of ltable 'keyfromval' */
let tpair = ls.h.strong.get(lstring.luaS_hashlongstr(ts));
assert(tpair.value == o);
ts = tpair.key.tsvalue(); /* re-use value previously stored */
}
return ts;
};
/*
** increment line number and skips newline sequence (any of
** \n, \r, \n\r, or \r\n)
*/
const inclinenumber = function(ls) {
let old = ls.current;
assert(currIsNewline(ls));
next(ls); /* skip '\n' or '\r' */
if (currIsNewline(ls) && ls.current !== old)
next(ls); /* skip '\n\r' or '\r\n' */
if (++ls.linenumber >= llimit.MAX_INT)
lexerror(ls, defs.to_luastring("chunk has too many lines", true), 0);
};
const luaX_setinput = function(L, ls, z, source, firstchar) {
ls.t = {
token: 0,
seminfo: new SemInfo()
};
ls.L = L;
ls.current = firstchar;
ls.lookahead = {
token: R.TK_EOS,
seminfo: new SemInfo()
};
ls.z = z;
ls.fs = null;
ls.linenumber = 1;
ls.lastline = 1;
ls.source = source;
ls.envn = lstring.luaS_newliteral(L, "_ENV");
};
const check_next1 = function(ls, c) {
if (ls.current === c.charCodeAt(0)) {
next(ls);
return true;
}
return false;
};
/*
** Check whether current char is in set 'set' (with two chars) and
** saves it
*/
const check_next2 = function(ls, set) {
if (ls.current === set[0].charCodeAt(0) || ls.current === set[1].charCodeAt(0)) {
save_and_next(ls);
return true;
}
return false;
};
const read_numeral = function(ls, seminfo) {
let expo = "Ee";
let first = ls.current;
assert(ljstype.lisdigit(ls.current));
save_and_next(ls);
if (first === char['0'] && check_next2(ls, "xX")) /* hexadecimal? */
expo = "Pp";
for (;;) {
if (check_next2(ls, expo)) /* exponent part? */
check_next2(ls, "-+"); /* optional exponent sign */
if (ljstype.lisxdigit(ls.current))
save_and_next(ls);
else if (ls.current === char['.'])
save_and_next(ls);
else break;
}
// save(ls, 0);
let obj = lobject.luaO_str2num(ls.buff.buffer);
if (obj === false) /* format error? */
lexerror(ls, defs.to_luastring("malformed number", true), R.TK_FLT);
if (obj.ttisinteger()) {
seminfo.i = obj.value;
return R.TK_INT;
} else {
assert(obj.ttisfloat());
seminfo.r = obj.value;
return R.TK_FLT;
}
};
const txtToken = function(ls, token) {
switch (token) {
case R.TK_NAME: case R.TK_STRING:
case R.TK_FLT: case R.TK_INT:
// save(ls, 0);
return lobject.luaO_pushfstring(ls.L, defs.to_luastring("'%s'", true), ls.buff.buffer);
default:
return luaX_token2str(ls, token);
}
};
const lexerror = function(ls, msg, token) {
msg = ldebug.luaG_addinfo(ls.L, msg, ls.source, ls.linenumber);
if (token)
lobject.luaO_pushfstring(ls.L, defs.to_luastring("%s near %s"), msg, txtToken(ls, token));
ldo.luaD_throw(ls.L, TS.LUA_ERRSYNTAX);
};
const luaX_syntaxerror = function(ls, msg) {
lexerror(ls, msg, ls.t.token);
};
/*
** skip a sequence '[=*[' or ']=*]'; if sequence is well formed, return
** its number of '='s; otherwise, return a negative number (-1 iff there
** are no '='s after initial bracket)
*/
const skip_sep = function(ls) {
let count = 0;
let s = ls.current;
assert(s === char['['] || s === char[']']);
save_and_next(ls);
while (ls.current === char['=']) {
save_and_next(ls);
count++;
}
return ls.current === s ? count : (-count) - 1;
};
const read_long_string = function(ls, seminfo, sep) {
let line = ls.linenumber; /* initial line (for error message) */
save_and_next(ls); /* skip 2nd '[' */
if (currIsNewline(ls)) /* string starts with a newline? */
inclinenumber(ls); /* skip it */
let skip = false;
for (; !skip ;) {
switch (ls.current) {
case lzio.EOZ: { /* error */
let what = seminfo ? "string" : "comment";
let msg = `unfinished long ${what} (starting at line ${line})`;
lexerror(ls, defs.to_luastring(msg), R.TK_EOS);
break;
}
case char[']']: {
if (skip_sep(ls) === sep) {
save_and_next(ls); /* skip 2nd ']' */
skip = true;
}
break;
}
case char['\n']: case char['\r']: {
save(ls, char['\n']);
inclinenumber(ls);
if (!seminfo) lzio.luaZ_resetbuffer(ls.buff);
break;
}
default: {
if (seminfo) save_and_next(ls);
else next(ls);
}
}
}
if (seminfo)
seminfo.ts = luaX_newstring(ls, ls.buff.buffer.slice(2 + sep, 2 + sep - 2 * (2 + sep)));
};
const esccheck = function(ls, c, msg) {
if (!c) {
if (ls.current !== lzio.EOZ)
save_and_next(ls); /* add current to buffer for error message */
lexerror(ls, msg, R.TK_STRING);
}
};
const gethexa = function(ls) {
save_and_next(ls);
esccheck(ls, ljstype.lisxdigit(ls.current), defs.to_luastring("hexadecimal digit expected", true));
return lobject.luaO_hexavalue(ls.current);
};
const readhexaesc = function(ls) {
let r = gethexa(ls);
r = (r << 4) + gethexa(ls);
lzio.luaZ_buffremove(ls.buff, 2); /* remove saved chars from buffer */
return r;
};
const readutf8desc = function(ls) {
let i = 4; /* chars to be removed: '\', 'u', '{', and first digit */
save_and_next(ls); /* skip 'u' */
esccheck(ls, ls.current === char['{'], defs.to_luastring("missing '{'", true));
let r = gethexa(ls); /* must have at least one digit */
save_and_next(ls);
while (ljstype.lisxdigit(ls.current)) {
i++;
r = (r << 4) + lobject.luaO_hexavalue(ls.current);
esccheck(ls, r <= 0x10FFFF, defs.to_luastring("UTF-8 value too large", true));
save_and_next(ls);
}
esccheck(ls, ls.current === char['}'], defs.to_luastring("missing '}'", true));
next(ls); /* skip '}' */
lzio.luaZ_buffremove(ls.buff, i); /* remove saved chars from buffer */
return r;
};
const utf8esc = function(ls) {
let u = lobject.luaO_utf8esc(readutf8desc(ls));
let buff = u.buff;
for (let n = u.n; n > 0; n--) /* add 'buff' to string */
save(ls, buff[lobject.UTF8BUFFSZ - n]);
};
const readdecesc = function(ls) {
let r = 0; /* result accumulator */
let i;
for (i = 0; i < 3 && ljstype.lisdigit(ls.current); i++) { /* read up to 3 digits */
r = 10 * r + ls.current - char['0'];
save_and_next(ls);
}
esccheck(ls, r <= 255, defs.to_luastring("decimal escape too large", true));
lzio.luaZ_buffremove(ls.buff, i); /* remove read digits from buffer */
return r;
};
const read_string = function(ls, del, seminfo) {
save_and_next(ls); /* keep delimiter (for error messages) */
while (ls.current !== del) {
switch (ls.current) {
case lzio.EOZ:
lexerror(ls, defs.to_luastring("unfinished string", true), R.TK_EOS);
break;
case char['\n']:
case char['\r']:
lexerror(ls, defs.to_luastring("unfinished string", true), R.TK_STRING);
break;
case char['\\']: { /* escape sequences */
save_and_next(ls); /* keep '\\' for error messages */
let will;
let c;
switch(ls.current) {
case char['a']: c = 7 /* \a isn't valid JS */; will = 'read_save'; break;
case char['b']: c = char['\b']; will = 'read_save'; break;
case char['f']: c = char['\f']; will = 'read_save'; break;
case char['n']: c = char['\n']; will = 'read_save'; break;
case char['r']: c = char['\r']; will = 'read_save'; break;
case char['t']: c = char['\t']; will = 'read_save'; break;
case char['v']: c = char['\v']; will = 'read_save'; break;
case char['x']: c = readhexaesc(ls); will = 'read_save'; break;
case char['u']: utf8esc(ls); will = 'no_save'; break;
case char['\n']: case char['\r']:
inclinenumber(ls); c = char['\n']; will = 'only_save'; break;
case char['\\']: case char['\"']: case char['\'']:
c = ls.current; will = 'read_save'; break;
case lzio.EOZ: will = 'no_save'; break; /* will raise an error next loop */
case char['z']: { /* zap following span of spaces */
lzio.luaZ_buffremove(ls.buff, 1); /* remove '\\' */
next(ls); /* skip the 'z' */
while (ljstype.lisspace(ls.current)) {
if (currIsNewline(ls)) inclinenumber(ls);
else next(ls);
}
will = 'no_save'; break;
}
default: {
esccheck(ls, ljstype.lisdigit(ls.current), defs.to_luastring("invalid escape sequence", true));
c = readdecesc(ls); /* digital escape '\ddd' */
will = 'only_save'; break;
}
}
if (will === 'read_save')
next(ls);
if (will === 'read_save' || will === 'only_save') {
lzio.luaZ_buffremove(ls.buff, 1); /* remove '\\' */
save(ls, c);
}
break;
}
default:
save_and_next(ls);
}
}
save_and_next(ls); /* skip delimiter */
seminfo.ts = luaX_newstring(ls, ls.buff.buffer.slice(1, ls.buff.n-1));
};
const token_to_index = Object.create(null); /* don't want to return true for e.g. 'hasOwnProperty' */
luaX_tokens.forEach((e, i)=>token_to_index[lstring.luaS_hash(defs.to_luastring(e))] = i);
const isreserved = function(w) {
let kidx = token_to_index[lstring.luaS_hashlongstr(w)];
return kidx !== void 0 && kidx <= 22;
};
const llex = function(ls, seminfo) {
lzio.luaZ_resetbuffer(ls.buff);
for (;;) {
assert(typeof ls.current == "number");
switch (ls.current) {
case char['\n']: case char['\r']: { /* line breaks */
inclinenumber(ls);
break;
}
case char[' ']: case char['\f']: case char['\t']: case char['\v']: { /* spaces */
next(ls);
break;
}
case char['-']: { /* '-' or '--' (comment) */
next(ls);
if (ls.current !== char['-']) return char['-'];
/* else is a comment */
next(ls);
if (ls.current === char['[']) { /* long comment? */
let sep = skip_sep(ls);
lzio.luaZ_resetbuffer(ls.buff); /* 'skip_sep' may dirty the buffer */
if (sep >= 0) {
read_long_string(ls, null, sep); /* skip long comment */
lzio.luaZ_resetbuffer(ls.buff); /* previous call may dirty the buff. */
break;
}
}
/* else short comment */
while (!currIsNewline(ls) && ls.current !== lzio.EOZ)
next(ls); /* skip until end of line (or end of file) */
break;
}
case char['[']: { /* long string or simply '[' */
let sep = skip_sep(ls);
if (sep >= 0) {
read_long_string(ls, seminfo, sep);
return R.TK_STRING;
} else if (sep !== -1) /* '[=...' missing second bracket */
lexerror(ls, defs.to_luastring("invalid long string delimiter", true), R.TK_STRING);
return char['['];
}
case char['=']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_EQ;
else return char['='];
}
case char['<']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_LE;
else if (check_next1(ls, '<')) return R.TK_SHL;
else return char['<'];
}
case char['>']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_GE;
else if (check_next1(ls, '>')) return R.TK_SHR;
else return char['>'];
}
case char['/']: {
next(ls);
if (check_next1(ls, '/')) return R.TK_IDIV;
else return char['/'];
}
case char['~']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_NE;
else return char['~'];
}
case char[':']: {
next(ls);
if (check_next1(ls, ':')) return R.TK_DBCOLON;
else return char[':'];
}
case char['"']: case char['\'']: { /* short literal strings */
read_string(ls, ls.current, seminfo);
return R.TK_STRING;
}
case char['.']: { /* '.', '..', '...', or number */
save_and_next(ls);
if (check_next1(ls, '.')) {
if (check_next1(ls, '.'))
return R.TK_DOTS; /* '...' */
else return R.TK_CONCAT; /* '..' */
}
else if (!ljstype.lisdigit(ls.current)) return char['.'];
else return read_numeral(ls, seminfo);
}
case char['0']: case char['1']: case char['2']: case char['3']: case char['4']:
case char['5']: case char['6']: case char['7']: case char['8']: case char['9']: {
return read_numeral(ls, seminfo);
}
case lzio.EOZ: {
return R.TK_EOS;
}
default: {
if (ljstype.lislalpha(ls.current)) { /* identifier or reserved word? */
do {
save_and_next(ls);
} while (ljstype.lislalnum(ls.current));
let ts = luaX_newstring(ls, ls.buff.buffer);
seminfo.ts = ts;
let kidx = token_to_index[lstring.luaS_hashlongstr(ts)];
if (kidx !== void 0 && kidx <= 22) /* reserved word? */
return kidx + FIRST_RESERVED;
else
return R.TK_NAME;
} else { /* single-char tokens (+ - / ...) */
let c = ls.current;
next(ls);
return c;
}
}
}
}
};
const luaX_next = function(ls) {
ls.lastline = ls.linenumber;
if (ls.lookahead.token !== R.TK_EOS) { /* is there a look-ahead token? */
ls.t.token = ls.lookahead.token; /* use this one */
ls.t.seminfo.i = ls.lookahead.seminfo.i;
ls.t.seminfo.r = ls.lookahead.seminfo.r;
ls.t.seminfo.ts = ls.lookahead.seminfo.ts; // TODO ?
ls.lookahead.token = R.TK_EOS; /* and discharge it */
} else
ls.t.token = llex(ls, ls.t.seminfo); /* read next token */
};
const luaX_lookahead = function(ls) {
assert(ls.lookahead.token === R.TK_EOS);
ls.lookahead.token = llex(ls, ls.lookahead.seminfo);
return ls.lookahead.token;
};
module.exports.FIRST_RESERVED = FIRST_RESERVED;
module.exports.LexState = LexState;
module.exports.RESERVED = RESERVED;
module.exports.isreserved = isreserved;
module.exports.luaX_lookahead = luaX_lookahead;
module.exports.luaX_newstring = luaX_newstring;
module.exports.luaX_next = luaX_next;
module.exports.luaX_setinput = luaX_setinput;
module.exports.luaX_syntaxerror = luaX_syntaxerror;
module.exports.luaX_token2str = luaX_token2str;
module.exports.luaX_tokens = luaX_tokens;
/***/ }),
/* 43 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const lua = __webpack_require__(3);
const linit = __webpack_require__(73);
const LUA_VERSUFFIX = "_" + lua.LUA_VERSION_MAJOR + "_" + lua.LUA_VERSION_MINOR;
module.exports.LUA_VERSUFFIX = LUA_VERSUFFIX;
const LUA_COLIBNAME = "coroutine";
module.exports.LUA_COLIBNAME = LUA_COLIBNAME;
module.exports.luaopen_coroutine = __webpack_require__(44).luaopen_coroutine;
const LUA_TABLIBNAME = "table";
module.exports.LUA_TABLIBNAME = LUA_TABLIBNAME;
module.exports.luaopen_table = __webpack_require__(48).luaopen_table;
if (false) {
const LUA_IOLIBNAME = "io";
module.exports.LUA_IOLIBNAME = LUA_IOLIBNAME;
module.exports.luaopen_io = require("./liolib.js").luaopen_io;
}
const LUA_OSLIBNAME = "os";
module.exports.LUA_OSLIBNAME = LUA_OSLIBNAME;
module.exports.luaopen_os = __webpack_require__(51).luaopen_os;
const LUA_STRLIBNAME = "string";
module.exports.LUA_STRLIBNAME = LUA_STRLIBNAME;
module.exports.luaopen_string = __webpack_require__(47).luaopen_string;
const LUA_UTF8LIBNAME = "utf8";
module.exports.LUA_UTF8LIBNAME = LUA_UTF8LIBNAME;
module.exports.luaopen_utf8 = __webpack_require__(49).luaopen_utf8;
const LUA_BITLIBNAME = "bit32";
module.exports.LUA_BITLIBNAME = LUA_BITLIBNAME;
// module.exports.luaopen_bit32 = require("./lbitlib.js").luaopen_bit32;
const LUA_MATHLIBNAME = "math";
module.exports.LUA_MATHLIBNAME = LUA_MATHLIBNAME;
module.exports.luaopen_math = __webpack_require__(45).luaopen_math;
const LUA_DBLIBNAME = "debug";
module.exports.LUA_DBLIBNAME = LUA_DBLIBNAME;
module.exports.luaopen_debug = __webpack_require__(50).luaopen_debug;
const LUA_LOADLIBNAME = "package";
module.exports.LUA_LOADLIBNAME = LUA_LOADLIBNAME;
module.exports.luaopen_package = __webpack_require__(53).luaopen_package;
module.exports.luaL_openlibs = linit.luaL_openlibs;
/***/ }),
/* 44 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const lua = __webpack_require__(3);
const lauxlib = __webpack_require__(9);
const getco = function(L) {
let co = lua.lua_tothread(L, 1);
lauxlib.luaL_argcheck(L, co, 1, lua.to_luastring("thread expected", true));
return co;
};
const auxresume = function(L, co, narg) {
if (!lua.lua_checkstack(co, narg)) {
lua.lua_pushliteral(L, "too many arguments to resume");
return -1; /* error flag */
}
if (lua.lua_status(co) === lua.LUA_OK && lua.lua_gettop(co) === 0) {
lua.lua_pushliteral(L, "cannot resume dead coroutine");
return -1; /* error flag */
}
lua.lua_xmove(L, co, narg);
let status = lua.lua_resume(co, L, narg);
if (status === lua.LUA_OK || status === lua.LUA_YIELD) {
let nres = lua.lua_gettop(co);
if (!lua.lua_checkstack(L, nres + 1)) {
lua.lua_pop(co, nres); /* remove results anyway */
lua.lua_pushliteral(L, "too many results to resume");
return -1; /* error flag */
}
lua.lua_xmove(co, L, nres); /* move yielded values */
return nres;
} else {
lua.lua_xmove(co, L, 1); /* move error message */
return -1; /* error flag */
}
};
const luaB_coresume = function(L) {
let co = getco(L);
let r = auxresume(L, co, lua.lua_gettop(L) - 1);
if (r < 0) {
lua.lua_pushboolean(L, 0);
lua.lua_insert(L, -2);
return 2; /* return false + error message */
} else {
lua.lua_pushboolean(L, 1);
lua.lua_insert(L, -(r + 1));
return r + 1; /* return true + 'resume' returns */
}
};
const luaB_auxwrap = function(L) {
let co = lua.lua_tothread(L, lua.lua_upvalueindex(1));
let r = auxresume(L, co, lua.lua_gettop(L));
if (r < 0) {
if (lua.lua_type(L, -1) === lua.LUA_TSTRING) { /* error object is a string? */
lauxlib.luaL_where(L, 1); /* add extra info */
lua.lua_insert(L, -2);
lua.lua_concat(L, 2);
}
return lua.lua_error(L); /* propagate error */
}
return r;
};
const luaB_cocreate = function(L) {
lauxlib.luaL_checktype(L, 1, lua.LUA_TFUNCTION);
let NL = lua.lua_newthread(L);
lua.lua_pushvalue(L, 1); /* move function to top */
lua.lua_xmove(L, NL, 1); /* move function from L to NL */
return 1;
};
const luaB_cowrap = function(L) {
luaB_cocreate(L);
lua.lua_pushcclosure(L, luaB_auxwrap, 1);
return 1;
};
const luaB_yield = function(L) {
return lua.lua_yield(L, lua.lua_gettop(L));
};
const luaB_costatus = function(L) {
let co = getco(L);
if (L === co) lua.lua_pushliteral(L, "running");
else {
switch (lua.lua_status(co)) {
case lua.LUA_YIELD:
lua.lua_pushliteral(L, "suspended");
break;
case lua.LUA_OK: {
let ar = new lua.lua_Debug();
if (lua.lua_getstack(co, 0, ar) > 0) /* does it have frames? */
lua.lua_pushliteral(L, "normal"); /* it is running */
else if (lua.lua_gettop(co) === 0)
lua.lua_pushliteral(L, "dead");
else
lua.lua_pushliteral(L, "suspended"); /* initial state */
break;
}
default: /* some error occurred */
lua.lua_pushliteral(L, "dead");
break;
}
}
return 1;
};
const luaB_yieldable = function(L) {
lua.lua_pushboolean(L, lua.lua_isyieldable(L));
return 1;
};
const luaB_corunning = function(L) {
lua.lua_pushboolean(L, lua.lua_pushthread(L));
return 2;
};
const co_funcs = {
"create": luaB_cocreate,
"isyieldable": luaB_yieldable,
"resume": luaB_coresume,
"running": luaB_corunning,
"status": luaB_costatus,
"wrap": luaB_cowrap,
"yield": luaB_yield
};
const luaopen_coroutine = function(L) {
lauxlib.luaL_newlib(L, co_funcs);
return 1;
};
module.exports.luaopen_coroutine = luaopen_coroutine;
/***/ }),
/* 45 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const seedrandom = __webpack_require__(46);
const lua = __webpack_require__(3);
const lauxlib = __webpack_require__(9);
const llimit = __webpack_require__(8);
const luaconf = __webpack_require__(18);
var RNG = seedrandom();
const math_randomseed = function(L) {
RNG = seedrandom(Math.abs(lauxlib.luaL_checknumber(L, 1)));
return 0;
};
const math_random = function(L) {
let low, up;
let r = RNG();
switch (lua.lua_gettop(L)) { /* check number of arguments */
case 0:
lua.lua_pushnumber(L, r); /* Number between 0 and 1 */
return 1;
case 1: {
low = 1;
up = lauxlib.luaL_checkinteger(L, 1);
break;
}
case 2: {
low = lauxlib.luaL_checkinteger(L, 1);
up = lauxlib.luaL_checkinteger(L, 2);
break;
}
default: return lauxlib.luaL_error(L, lua.to_luastring("wrong number of arguments", true));
}
/* random integer in the interval [low, up] */
lauxlib.luaL_argcheck(L, low <= up, 1, lua.to_luastring("interval is empty", true));
lauxlib.luaL_argcheck(L, low >= 0 || up <= llimit.MAX_INT + low, 1,
lua.to_luastring("interval too large", true));
r *= (up - low) + 1;
lua.lua_pushinteger(L, Math.floor(r) + low);
return 1;
};
const math_abs = function(L) {
if (lua.lua_isinteger(L, 1)) {
let n = lua.lua_tointeger(L, 1);
if (n < 0) n = (-n)|0;
lua.lua_pushinteger(L, n);
}
else
lua.lua_pushnumber(L, Math.abs(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_sin = function(L) {
lua.lua_pushnumber(L, Math.sin(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_cos = function(L) {
lua.lua_pushnumber(L, Math.cos(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_tan = function(L) {
lua.lua_pushnumber(L, Math.tan(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_asin = function(L) {
lua.lua_pushnumber(L, Math.asin(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_acos = function(L) {
lua.lua_pushnumber(L, Math.acos(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_atan = function(L) {
let y = lauxlib.luaL_checknumber(L, 1);
let x = lauxlib.luaL_optnumber(L, 2, 1);
lua.lua_pushnumber(L, Math.atan2(y, x));
return 1;
};
const math_toint = function(L) {
let n = lua.lua_tointegerx(L, 1);
if (n !== false)
lua.lua_pushinteger(L, n);
else {
lauxlib.luaL_checkany(L, 1);
lua.lua_pushnil(L); /* value is not convertible to integer */
}
return 1;
};
const pushnumint = function(L, d) {
let n = luaconf.lua_numbertointeger(d);
if (n !== false) /* does 'd' fit in an integer? */
lua.lua_pushinteger(L, n); /* result is integer */
else
lua.lua_pushnumber(L, d); /* result is float */
};
const math_floor = function(L) {
if (lua.lua_isinteger(L, 1))
lua.lua_settop(L, 1);
else
pushnumint(L, Math.floor(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_ceil = function(L) {
if (lua.lua_isinteger(L, 1))
lua.lua_settop(L, 1);
else
pushnumint(L, Math.ceil(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_sqrt = function(L) {
lua.lua_pushnumber(L, Math.sqrt(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_ult = function(L) {
let a = lauxlib.luaL_checkinteger(L, 1);
let b = lauxlib.luaL_checkinteger(L, 2);
lua.lua_pushboolean(L, (a >= 0)?(b<0 || a<b):(b<0 && a<b));
return 1;
};
const math_log = function(L) {
let x = lauxlib.luaL_checknumber(L, 1);
let res;
if (lua.lua_isnoneornil(L, 2))
res = Math.log(x);
else {
let base = lauxlib.luaL_checknumber(L, 2);
if (base === 2)
res = Math.log2(x);
else if (base === 10)
res = Math.log10(x);
else
res = Math.log(x)/Math.log(base);
}
lua.lua_pushnumber(L, res);
return 1;
};
const math_exp = function(L) {
lua.lua_pushnumber(L, Math.exp(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_deg = function(L) {
lua.lua_pushnumber(L, lauxlib.luaL_checknumber(L, 1) * (180 / Math.PI));
return 1;
};
const math_rad = function(L) {
lua.lua_pushnumber(L, lauxlib.luaL_checknumber(L, 1) * (Math.PI / 180));
return 1;
};
const math_min = function(L) {
let n = lua.lua_gettop(L); /* number of arguments */
let imin = 1; /* index of current minimum value */
lauxlib.luaL_argcheck(L, n >= 1, 1, lua.to_luastring("value expected", true));
for (let i = 2; i <= n; i++){
if (lua.lua_compare(L, i, imin, lua.LUA_OPLT))
imin = i;
}
lua.lua_pushvalue(L, imin);
return 1;
};
const math_max = function(L) {
let n = lua.lua_gettop(L); /* number of arguments */
let imax = 1; /* index of current minimum value */
lauxlib.luaL_argcheck(L, n >= 1, 1, lua.to_luastring("value expected", true));
for (let i = 2; i <= n; i++){
if (lua.lua_compare(L, imax, i, lua.LUA_OPLT))
imax = i;
}
lua.lua_pushvalue(L, imax);
return 1;
};
const math_type = function(L) {
if (lua.lua_type(L, 1) === lua.LUA_TNUMBER) {
if (lua.lua_isinteger(L, 1))
lua.lua_pushliteral(L, "integer");
else
lua.lua_pushliteral(L, "float");
} else {
lauxlib.luaL_checkany(L, 1);
lua.lua_pushnil(L);
}
return 1;
};
const math_fmod = function(L) {
if (lua.lua_isinteger(L, 1) && lua.lua_isinteger(L, 2)) {
let d = lua.lua_tointeger(L, 2);
/* no special case needed for -1 in javascript */
if (d === 0) {
lauxlib.luaL_argerror(L, 2, lua.to_luastring("zero", true));
} else
lua.lua_pushinteger(L, (lua.lua_tointeger(L, 1) % d)|0);
} else {
let a = lauxlib.luaL_checknumber(L, 1);
let b = lauxlib.luaL_checknumber(L, 2);
lua.lua_pushnumber(L, a%b);
}
return 1;
};
const math_modf = function(L) {
if (lua.lua_isinteger(L, 1)) {
lua.lua_settop(L, 1); /* number is its own integer part */
lua.lua_pushnumber(L, 0); /* no fractional part */
} else {
let n = lauxlib.luaL_checknumber(L, 1);
let ip = n < 0 ? Math.ceil(n) : Math.floor(n);
pushnumint(L, ip);
lua.lua_pushnumber(L, n === ip ? 0 : n - ip);
}
return 2;
};
const mathlib = {
"abs": math_abs,
"acos": math_acos,
"asin": math_asin,
"atan": math_atan,
"ceil": math_ceil,
"cos": math_cos,
"deg": math_deg,
"exp": math_exp,
"floor": math_floor,
"fmod": math_fmod,
"log": math_log,
"max": math_max,
"min": math_min,
"modf": math_modf,
"rad": math_rad,
"random": math_random,
"randomseed": math_randomseed,
"sin": math_sin,
"sqrt": math_sqrt,
"tan": math_tan,
"tointeger": math_toint,
"type": math_type,
"ult": math_ult
};
const luaopen_math = function(L) {
lauxlib.luaL_newlib(L, mathlib);
lua.lua_pushnumber(L, Math.PI);
lua.lua_setfield(L, -2, lua.to_luastring("pi", true));
lua.lua_pushnumber(L, Infinity);
lua.lua_setfield(L, -2, lua.to_luastring("huge", true));
lua.lua_pushinteger(L, llimit.MAX_INT);
lua.lua_setfield(L, -2, lua.to_luastring("maxinteger", true));
lua.lua_pushinteger(L, llimit.MIN_INT);
lua.lua_setfield(L, -2, lua.to_luastring("mininteger", true));
return 1;
};
module.exports.luaopen_math = luaopen_math;
/***/ }),
/* 46 */
/***/ (function(module, exports, __webpack_require__) {
// A library of seedable RNGs implemented in Javascript.
//
// Usage:
//
// var seedrandom = require('seedrandom');
// var random = seedrandom(1); // or any seed.
// var x = random(); // 0 <= x < 1. Every bit is random.
// var x = random.quick(); // 0 <= x < 1. 32 bits of randomness.
// alea, a 53-bit multiply-with-carry generator by Johannes Baagøe.
// Period: ~2^116
// Reported to pass all BigCrush tests.
var alea = __webpack_require__(75);
// xor128, a pure xor-shift generator by George Marsaglia.
// Period: 2^128-1.
// Reported to fail: MatrixRank and LinearComp.
var xor128 = __webpack_require__(76);
// xorwow, George Marsaglia's 160-bit xor-shift combined plus weyl.
// Period: 2^192-2^32
// Reported to fail: CollisionOver, SimpPoker, and LinearComp.
var xorwow = __webpack_require__(77);
// xorshift7, by François Panneton and Pierre L'ecuyer, takes
// a different approach: it adds robustness by allowing more shifts
// than Marsaglia's original three. It is a 7-shift generator
// with 256 bits, that passes BigCrush with no systmatic failures.
// Period 2^256-1.
// No systematic BigCrush failures reported.
var xorshift7 = __webpack_require__(78);
// xor4096, by Richard Brent, is a 4096-bit xor-shift with a
// very long period that also adds a Weyl generator. It also passes
// BigCrush with no systematic failures. Its long period may
// be useful if you have many generators and need to avoid
// collisions.
// Period: 2^4128-2^32.
// No systematic BigCrush failures reported.
var xor4096 = __webpack_require__(79);
// Tyche-i, by Samuel Neves and Filipe Araujo, is a bit-shifting random
// number generator derived from ChaCha, a modern stream cipher.
// https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf
// Period: ~2^127
// No systematic BigCrush failures reported.
var tychei = __webpack_require__(80);
// The original ARC4-based prng included in this library.
// Period: ~2^1600
var sr = __webpack_require__(81);
sr.alea = alea;
sr.xor128 = xor128;
sr.xorwow = xorwow;
sr.xorshift7 = xorshift7;
sr.xor4096 = xor4096;
sr.tychei = tychei;
module.exports = sr;
/***/ }),
/* 47 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const sprintf = __webpack_require__(34).sprintf;
const lauxlib = __webpack_require__(9);
const lua = __webpack_require__(3);
const luaconf = __webpack_require__(18);
const llimit = __webpack_require__(8);
const sL_ESC = '%';
const L_ESC = sL_ESC.charCodeAt(0);
/*
** maximum number of captures that a pattern can do during
** pattern-matching. This limit is arbitrary, but must fit in
** an unsigned char.
*/
const LUA_MAXCAPTURES = 32;
// (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX))
const MAXSIZE = 2147483647;
/* Give natural (i.e. strings end at the first \0) length of a string represented by an array of bytes */
const strlen = function(s) {
let len = s.indexOf(0);
return len > -1 ? len : s.length;
};
/* translate a relative string position: negative means back from end */
const posrelat = function(pos, len) {
if (pos >= 0) return pos;
else if (0 - pos > len) return 0;
else return len + pos + 1;
};
const str_sub = function(L) {
let s = lauxlib.luaL_checkstring(L, 1);
let l = s.length;
let start = posrelat(lauxlib.luaL_checkinteger(L, 2), l);
let end = posrelat(lauxlib.luaL_optinteger(L, 3, -1), l);
if (start < 1) start = 1;
if (end > l) end = l;
if (start <= end)
lua.lua_pushstring(L, s.slice(start - 1, (start - 1) + (end - start + 1)));
else lua.lua_pushliteral(L, "");
return 1;
};
const str_len = function(L) {
lua.lua_pushinteger(L, lauxlib.luaL_checkstring(L, 1).length);
return 1;
};
const str_char = function(L) {
let n = lua.lua_gettop(L); /* number of arguments */
let p = [];
for (let i = 1; i <= n; i++) {
let c = lauxlib.luaL_checkinteger(L, i);
lauxlib.luaL_argcheck(L, c >= 0 && c <= 255, "value out of range"); // Strings are 8-bit clean
p.push(c);
}
lua.lua_pushstring(L, p);
return 1;
};
const writer = function(L, b, size, B) {
B.push(...b.slice(0, size));
return 0;
};
const str_dump = function(L) {
let b = [];
let strip = lua.lua_toboolean(L, 2);
lauxlib.luaL_checktype(L, 1, lua.LUA_TFUNCTION);
lua.lua_settop(L, 1);
if (lua.lua_dump(L, writer, b, strip) !== 0)
return lauxlib.luaL_error(L, lua.to_luastring("unable to dump given function"));
lua.lua_pushstring(L, b);
return 1;
};
const SIZELENMOD = luaconf.LUA_NUMBER_FRMLEN.length + 1;
const L_NBFD = 1;
/*
** Add integer part of 'x' to buffer and return new 'x'
*/
const adddigit = function(buff, n, x) {
let d = Math.floor(x); /* get integer part from 'x' */
buff[n] = d < 10 ? d + '0'.charCodeAt(0) : d - 10 + 'a'.charCodeAt(0); /* add to buffer */
return x - d; /* return what is left */
};
const num2straux = function(x) {
/* if 'inf' or 'NaN', format it like '%g' */
if (Object.is(x, Infinity))
return lua.to_luastring('inf', true).slice(0);
else if (Object.is(x, -Infinity))
return lua.to_luastring('-inf', true).slice(0);
else if (Number.isNaN(x))
return lua.to_luastring('nan', true).slice(0);
else if (x === 0) { /* can be -0... */
/* create "0" or "-0" followed by exponent */
let zero = sprintf(luaconf.LUA_NUMBER_FMT + "x0p+0", x);
if (Object.is(x, -0))
zero = "-" + zero;
return lua.to_luastring(zero);
} else {
let buff = [];
let fe = luaconf.frexp(x); /* 'x' fraction and exponent */
let m = fe[0];
let e = fe[1];
let n = 0; /* character count */
if (m < 0) { /* is number negative? */
buff[n++] = '-'.charCodeAt(0); /* add signal */
m = -m; /* make it positive */
}
buff[n++] = '0'.charCodeAt(0);
buff[n++] = 'x'.charCodeAt(0); /* add "0x" */
m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */
e -= L_NBFD; /* this digit goes before the radix point */
if (m > 0) { /* more digits? */
buff[n++] = luaconf.lua_getlocaledecpoint().charCodeAt(0); /* add radix point */
do { /* add as many digits as needed */
m = adddigit(buff, n++, m * 16);
} while (m > 0);
}
let exp = lua.to_luastring(sprintf("p%+d", e));
return buff.concat(exp);
}
};
const lua_number2strx = function(L, fmt, x) {
let buff = num2straux(x);
if (fmt[SIZELENMOD] === 'A'.charCodeAt(0)) {
for (let i = 0; i < buff.length; i++)
buff[i] = String.fromCharCode(buff[i]).toUpperCase().charCodeAt(0);
} else if (fmt[SIZELENMOD] !== 'a'.charCodeAt(0))
lauxlib.luaL_error(L, lua.to_luastring("modifiers for format '%%a'/'%%A' not implemented"));
return buff;
};
/*
** Maximum size of each formatted item. This maximum size is produced
** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.',
** and '\0') + number of decimal digits to represent maxfloat (which
** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra
** expenses", such as locale-dependent stuff)
*/
const MAX_ITEM = 120;// TODO: + l_mathlim(MAX_10_EXP);
/* valid flags in a format specification */
const FLAGS = ["-".charCodeAt(0), "+".charCodeAt(0), " ".charCodeAt(0), "#".charCodeAt(0), "0".charCodeAt(0)];
/*
** maximum size of each format specification (such as "%-099.99d")
*/
const MAX_FORMAT = 32;
// TODO: locale ? and do it better
const isalpha = e => ('a'.charCodeAt(0) <= e && e <= 'z'.charCodeAt(0)) || (e >= 'A'.charCodeAt(0) && e <= 'Z'.charCodeAt(0));
const isdigit = e => '0'.charCodeAt(0) <= e && e <= '9'.charCodeAt(0);
const iscntrl = e => (0x00 <= e && e <= 0x1f) || e === 0x7f;
const isgraph = e => e > 32 && e < 127; // TODO: Will only work for ASCII
const islower = e => /^[a-z]$/.test(String.fromCharCode(e));
const isupper = e => /^[A-Z]$/.test(String.fromCharCode(e));
const isalnum = e => /^[a-zA-Z0-9]$/.test(String.fromCharCode(e));
const ispunct = e => isgraph(e) && !isalnum(e);
const isspace = e => /^\s$/.test(String.fromCharCode(e));
const isxdigit = e => /^[0-9A-Fa-f]$/.test(String.fromCharCode(e));
// Concat 2 arrays by modifying the first one
const concat = function (a1, a2) {
for (let i = 0; i < a2.length; i++)
a1.push(a2[i]);
};
const addquoted = function(b, s) {
b.push('"'.charCodeAt(0));
let len = s.length;
while (len--) {
if (s[0] === '"'.charCodeAt(0) || s[0] === '\\'.charCodeAt(0) || s[0] === '\n'.charCodeAt(0)) {
b.push('\\'.charCodeAt(0));
b.push(s[0]);
} else if (iscntrl(s[0])) {
let buff = [];
if (!isdigit(s[1]))
buff = lua.to_luastring(sprintf("\\%d", s[0]));
else
buff = lua.to_luastring(sprintf("\\%03d", s[0]));
concat(b, buff);
} else
b.push(s[0]);
s = s.slice(1);
}
b.push('"'.charCodeAt(0));
};
/*
** Ensures the 'buff' string uses a dot as the radix character.
*/
const checkdp = function(buff) {
if (buff.indexOf('.'.charCodeAt(0)) < 0) { /* no dot? */
let point = luaconf.lua_getlocaledecpoint().charCodeAt(0); /* try locale point */
let ppoint = buff.indexOf(point);
if (ppoint) buff[ppoint] = '.'; /* change it to a dot */
}
};
const addliteral = function(L, b, arg) {
switch(lua.lua_type(L, arg)) {
case lua.LUA_TSTRING: {
let s = lua.lua_tostring(L, arg);
addquoted(b, s, s.length);
break;
}
case lua.LUA_TNUMBER: {
if (!lua.lua_isinteger(L, arg)) { /* float? */
let n = lua.lua_tonumber(L, arg); /* write as hexa ('%a') */
concat(b, lua_number2strx(L, lua.to_luastring(`%${luaconf.LUA_INTEGER_FRMLEN}a`), n));
checkdp(b); /* ensure it uses a dot */
} else { /* integers */
let n = lua.lua_tointeger(L, arg);
let format = (n === llimit.LUA_MININTEGER) /* corner case? */
? "0x%" + luaconf.LUA_INTEGER_FRMLEN + "x" /* use hexa */
: luaconf.LUA_INTEGER_FMT; /* else use default format */
concat(b, lua.to_luastring(sprintf(format, n)));
}
break;
}
case lua.LUA_TNIL: case lua.LUA_TBOOLEAN: {
concat(b, lauxlib.luaL_tolstring(L, arg));
break;
}
default: {
lauxlib.luaL_argerror(L, arg, lua.to_luastring("value has no literal form", true));
}
}
};
const scanformat = function(L, strfrmt, form) {
let p = strfrmt;
while (p[0] !== 0 && FLAGS.indexOf(p[0]) >= 0) p = p.slice(1); /* skip flags */
if (strfrmt.length - p.length >= FLAGS.length)
lauxlib.luaL_error(L, lua.to_luastring("invalid format (repeated flags)", true));
if (isdigit(p[0])) p = p.slice(1); /* skip width */
if (isdigit(p[0])) p = p.slice(1); /* (2 digits at most) */
if (p[0] === '.'.charCodeAt(0)) {
p = p.slice(1);
if (isdigit(p[0])) p = p.slice(1); /* skip precision */
if (isdigit(p[0])) p = p.slice(1); /* (2 digits at most) */
}
if (isdigit(p[0]))
lauxlib.luaL_error(L, lua.to_luastring("invalid format (width or precision too long)", true));
form[0] = "%".charCodeAt(0);
for (let i = 0; i < strfrmt.length - p.length + 1; i++)
form[i + 1] = strfrmt[i];
// form[strfrmt.length - p.length + 2] = 0;
return {
form: form,
p: p
};
};
/*
** add length modifier into formats
*/
const addlenmod = function(form, lenmod) {
let l = form.length;
let lm = lenmod.length;
let spec = form[l - 1];
for (let i = 0; i < lenmod.length; i++)
form[i + l - 1] = lenmod[i];
form[l + lm - 1] = spec;
// form[l + lm] = 0;
return form;
};
const str_format = function(L) {
let top = lua.lua_gettop(L);
let arg = 1;
let strfrmt = lauxlib.luaL_checkstring(L, arg);
let b = [];
while (strfrmt.length > 0) {
if (strfrmt[0] !== L_ESC) {
b.push(strfrmt[0]);
strfrmt = strfrmt.slice(1);
} else if ((strfrmt = strfrmt.slice(1))[0] === L_ESC) {
b.push(strfrmt[0]);
strfrmt = strfrmt.slice(1);
} else { /* format item */
let form = []; /* to store the format ('%...') */
if (++arg > top)
lauxlib.luaL_argerror(L, arg, lua.to_luastring("no value", true));
let f = scanformat(L, strfrmt, form);
strfrmt = f.p;
form = f.form;
switch (String.fromCharCode(strfrmt[0])) {
case 'c': {
strfrmt = strfrmt.slice(1);
// concat(b, lua.to_luastring(sprintf(String.fromCharCode(...form), lauxlib.luaL_checkinteger(L, arg))));
b.push(lauxlib.luaL_checkinteger(L, arg));
break;
}
case 'd': case 'i':
case 'o': case 'u': case 'x': case 'X': {
strfrmt = strfrmt.slice(1);
let n = lauxlib.luaL_checkinteger(L, arg);
form = addlenmod(form, luaconf.LUA_INTEGER_FRMLEN.split('').map(e => e.charCodeAt(0)));
concat(b, lua.to_luastring(sprintf(String.fromCharCode(...form), n)));
break;
}
case 'a': case 'A': {
strfrmt = strfrmt.slice(1);
form = addlenmod(form, luaconf.LUA_INTEGER_FRMLEN.split('').map(e => e.charCodeAt(0)));
concat(b, lua_number2strx(L, form, lauxlib.luaL_checknumber(L, arg)));
break;
}
case 'e': case 'E': case 'f':
case 'g': case 'G': {
strfrmt = strfrmt.slice(1);
let n = lauxlib.luaL_checknumber(L, arg);
form = addlenmod(form, luaconf.LUA_INTEGER_FRMLEN.split('').map(e => e.charCodeAt(0)));
concat(b, lua.to_luastring(sprintf(String.fromCharCode(...form), n)));
break;
}
case 'q': {
strfrmt = strfrmt.slice(1);
addliteral(L, b, arg);
break;
}
case 's': {
strfrmt = strfrmt.slice(1);
let s = lauxlib.luaL_tolstring(L, arg);
if (form.length <= 2 || form[2] === 0) { /* no modifiers? */
concat(b, s); /* keep entire string */
lua.lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
} else {
lauxlib.luaL_argcheck(L, s.length === strlen(s), arg, lua.to_luastring("string contains zeros", true));
if (form.indexOf('.'.charCodeAt(0)) < 0 && s.length >= 100) {
/* no precision and string is too long to be formatted */
concat(b, s); /* keep entire string */
lua.lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
} else { /* format the string into 'buff' */
// TODO: will fail if s is not valid UTF-8
concat(b, lua.to_luastring(sprintf(String.fromCharCode(...form), lua.to_jsstring(s))));
lua.lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
}
}
break;
}
default: { /* also treat cases 'pnLlh' */
return lauxlib.luaL_error(L, lua.to_luastring("invalid option '%%%c' to 'format'"), strfrmt[0]);
}
}
}
}
lua.lua_pushstring(L, b);
return 1;
};
/* value used for padding */
const LUAL_PACKPADBYTE = 0x00;
/* maximum size for the binary representation of an integer */
const MAXINTSIZE = 16;
const SZINT = 4; // Size of lua_Integer
/* number of bits in a character */
const NB = 8;
/* mask for one character (NB 1's) */
const MC = ((1 << NB) - 1);
const MAXALIGN = 8;
/*
** information to pack/unpack stuff
*/
class Header {
constructor(L) {
this.L = L;
this.islittle = true;
this.maxalign = 1;
}
}
/*
** options for pack/unpack
*/
const KOption = {
Kint: 0, /* signed integers */
Kuint: 1, /* unsigned integers */
Kfloat: 2, /* floating-point numbers */
Kchar: 3, /* fixed-length strings */
Kstring: 4, /* strings with prefixed length */
Kzstr: 5, /* zero-terminated strings */
Kpadding: 6, /* padding */
Kpaddalign: 7, /* padding for alignment */
Knop: 8 /* no-op (configuration or spaces) */
};
const digit = function(c) {
return '0'.charCodeAt(0) <= c && c <= '9'.charCodeAt(0);
};
const getnum = function(fmt, df) {
if (fmt.off >= fmt.s.length || !digit(fmt.s[fmt.off])) /* no number? */
return df; /* return default value */
else {
let a = 0;
do {
a = a * 10 + (fmt.s[fmt.off++] - '0'.charCodeAt(0));
} while (fmt.off < fmt.s.length && digit(fmt.s[fmt.off]) && a <= (MAXSIZE - 9)/10);
return a;
}
};
/*
** Read an integer numeral and raises an error if it is larger
** than the maximum size for integers.
*/
const getnumlimit = function(h, fmt, df) {
let sz = getnum(fmt, df);
if (sz > MAXINTSIZE || sz <= 0)
lauxlib.luaL_error(h.L, lua.to_luastring("integral size (%d) out of limits [1,%d]"), sz, MAXINTSIZE);
return sz;
};
/*
** Read and classify next option. 'size' is filled with option's size.
*/
const getoption = function(h, fmt) {
let r = {
opt: NaN,
size: NaN
};
r.opt = fmt.s[fmt.off++];
r.size = 0; /* default */
switch (r.opt) {
case 'b'.charCodeAt(0): r.size = 1; r.opt = KOption.Kint; return r; // sizeof(char): 1
case 'B'.charCodeAt(0): r.size = 1; r.opt = KOption.Kuint; return r;
case 'h'.charCodeAt(0): r.size = 2; r.opt = KOption.Kint; return r; // sizeof(short): 2
case 'H'.charCodeAt(0): r.size = 2; r.opt = KOption.Kuint; return r;
case 'l'.charCodeAt(0): r.size = 4; r.opt = KOption.Kint; return r; // sizeof(long): 4
case 'L'.charCodeAt(0): r.size = 4; r.opt = KOption.Kuint; return r;
case 'j'.charCodeAt(0): r.size = 4; r.opt = KOption.Kint; return r; // sizeof(lua_Integer): 4
case 'J'.charCodeAt(0): r.size = 4; r.opt = KOption.Kuint; return r;
case 'T'.charCodeAt(0): r.size = 4; r.opt = KOption.Kuint; return r; // sizeof(size_t): 4
case 'f'.charCodeAt(0): r.size = 4; r.opt = KOption.Kfloat; return r; // sizeof(float): 4
case 'd'.charCodeAt(0): r.size = 8; r.opt = KOption.Kfloat; return r; // sizeof(double): 8
case 'n'.charCodeAt(0): r.size = 8; r.opt = KOption.Kfloat; return r; // sizeof(lua_Number): 8
case 'i'.charCodeAt(0): r.size = getnumlimit(h, fmt, 4); r.opt = KOption.Kint; return r; // sizeof(int): 4
case 'I'.charCodeAt(0): r.size = getnumlimit(h, fmt, 4); r.opt = KOption.Kuint; return r;
case 's'.charCodeAt(0): r.size = getnumlimit(h, fmt, 4); r.opt = KOption.Kstring; return r;
case 'c'.charCodeAt(0): {
r.size = getnum(fmt, -1);
if (r.size === -1)
lauxlib.luaL_error(h.L, lua.to_luastring("missing size for format option 'c'"));
r.opt = KOption.Kchar;
return r;
}
case 'z'.charCodeAt(0): r.opt = KOption.Kzstr; return r;
case 'x'.charCodeAt(0): r.size = 1; r.opt = KOption.Kpadding; return r;
case 'X'.charCodeAt(0): r.opt = KOption.Kpaddalign; return r;
case ' '.charCodeAt(0): break;
case '<'.charCodeAt(0): h.islittle = true; break;
case '>'.charCodeAt(0): h.islittle = false; break;
case '='.charCodeAt(0): h.islittle = true; break;
case '!'.charCodeAt(0): h.maxalign = getnumlimit(h, fmt, MAXALIGN); break;
default: lauxlib.luaL_error(h.L, lua.to_luastring("invalid format option '%c'"), r.opt);
}
r.opt = KOption.Knop;
return r;
};
/*
** Read, classify, and fill other details about the next option.
** 'psize' is filled with option's size, 'notoalign' with its
** alignment requirements.
** Local variable 'size' gets the size to be aligned. (Kpadal option
** always gets its full alignment, other options are limited by
** the maximum alignment ('maxalign'). Kchar option needs no alignment
** despite its size.
*/
const getdetails = function(h, totalsize, fmt) {
let r = {
opt: NaN,
size: NaN,
ntoalign: NaN
};
let opt = getoption(h, fmt);
r.size = opt.size;
r.opt = opt.opt;
let align = r.size; /* usually, alignment follows size */
if (r.opt === KOption.Kpaddalign) { /* 'X' gets alignment from following option */
if (fmt.off >= fmt.s.length || fmt.s[fmt.off] === 0)
lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("invalid next option for option 'X'", true));
else {
let o = getoption(h, fmt);
align = o.size;
o = o.opt;
if (o === KOption.Kchar || align === 0)
lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("invalid next option for option 'X'", true));
}
}
if (align <= 1 || r.opt === KOption.Kchar) /* need no alignment? */
r.ntoalign = 0;
else {
if (align > h.maxalign) /* enforce maximum alignment */
align = h.maxalign;
if ((align & (align -1)) !== 0) /* is 'align' not a power of 2? */
lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("format asks for alignment not power of 2", true));
r.ntoalign = (align - (totalsize & (align - 1))) & (align - 1);
}
return r;
};
/*
** Pack integer 'n' with 'size' bytes and 'islittle' endianness.
** The final 'if' handles the case when 'size' is larger than
** the size of a Lua integer, correcting the extra sign-extension
** bytes if necessary (by default they would be zeros).
*/
const packint = function(b, n, islittle, size, neg) {
let buff = new Array(size);
buff[islittle ? 0 : size - 1] = n & MC; /* first byte */
for (let i = 1; i < size; i++) {
n >>= NB;
buff[islittle ? i : size - 1 - i] = n & MC;
}
if (neg && size > SZINT) { /* negative number need sign extension? */
for (let i = SZINT; i < size; i++) /* correct extra bytes */
buff[islittle ? i : size - 1 - i] = MC;
}
b.push(...buff); /* add result to buffer */
};
const packnum = function(b, n, islittle, size) {
let dv = new DataView(new ArrayBuffer(size));
if (size === 4) dv.setFloat32(0, n, islittle);
else dv.setFloat64(0, n, islittle);
for (let i = 0; i < size; i++)
b.push(dv.getUint8(i, islittle));
};
const str_pack = function(L) {
let b = [];
let h = new Header(L);
let fmt = {
s: lauxlib.luaL_checkstring(L, 1), /* format string */
off: 0
};
let arg = 1; /* current argument to pack */
let totalsize = 0; /* accumulate total size of result */
lua.lua_pushnil(L); /* mark to separate arguments from string buffer */
while (fmt.off < fmt.s.length) {
let details = getdetails(h, totalsize, fmt);
let opt = details.opt;
let size = details.size;
let ntoalign = details.ntoalign;
totalsize += ntoalign + size;
while (ntoalign-- > 0)
b.push(LUAL_PACKPADBYTE); /* fill alignment */
arg++;
switch (opt) {
case KOption.Kint: { /* signed integers */
let n = lauxlib.luaL_checkinteger(L, arg);
if (size < SZINT) { /* need overflow check? */
let lim = 1 << (size * 8) - 1;
lauxlib.luaL_argcheck(L, -lim <= n && n < lim, arg, lua.to_luastring("integer overflow", true));
}
packint(b, n, h.islittle, size, n < 0);
break;
}
case KOption.Kuint: { /* unsigned integers */
let n = lauxlib.luaL_checkinteger(L, arg);
if (size < SZINT)
lauxlib.luaL_argcheck(L, (n>>>0) < (1 << (size * NB)), arg, lua.to_luastring("unsigned overflow", true));
packint(b, n>>>0, h.islittle, size, false);
break;
}
case KOption.Kfloat: { /* floating-point options */
let n = lauxlib.luaL_checknumber(L, arg); /* get argument */
packnum(b, n, h.islittle, size);
break;
}
case KOption.Kchar: { /* fixed-size string */
let s = lauxlib.luaL_checkstring(L, arg);
let len = s.length;
lauxlib.luaL_argcheck(L, len <= size, arg, lua.to_luastring("string longer than given size", true));
b.push(...s); /* add string */
while (len++ < size) /* pad extra space */
b.push(LUAL_PACKPADBYTE);
break;
}
case KOption.Kstring: { /* strings with length count */
let s = lauxlib.luaL_checkstring(L, arg);
let len = s.length;
lauxlib.luaL_argcheck(L, size >= 4 /* sizeof(size_t) */ ||
len < (1 << (size * NB)),
arg, lua.to_luastring("string length does not fit in given size", true));
packint(b, len, h.islittle, size, 0); /* pack length */
b.push(...s);
totalsize += len;
break;
}
case KOption.Kzstr: { /* zero-terminated string */
let s = lauxlib.luaL_checkstring(L, arg);
let len = s.length;
lauxlib.luaL_argcheck(L, s.indexOf(0) < 0, arg, lua.to_luastring("strings contains zeros", true));
b.push(...s);
b.push(0); /* add zero at the end */
totalsize += len + 1;
break;
}
case KOption.Kpadding: b.push(LUAL_PACKPADBYTE); /* fall through */
case KOption.Kpaddalign: case KOption.Knop:
arg--; /* undo increment */
break;
}
}
lua.lua_pushstring(L, b);
return 1;
};
const str_reverse = function(L) {
lua.lua_pushstring(L, lauxlib.luaL_checkstring(L, 1).slice(0).reverse());
return 1;
};
const str_lower = function(L) {
// TODO: will fail on invalid UTF-8
lua.lua_pushstring(L, lua.to_luastring(lua.to_jsstring(lauxlib.luaL_checkstring(L, 1)).toLowerCase()));
return 1;
};
const str_upper = function(L) {
// TODO: will fail on invalid UTF-8
lua.lua_pushstring(L, lua.to_luastring(lua.to_jsstring(lauxlib.luaL_checkstring(L, 1)).toUpperCase()));
return 1;
};
const str_rep = function(L) {
let s = lauxlib.luaL_checkstring(L, 1);
let n = lauxlib.luaL_checkinteger(L, 2);
let sep = lauxlib.luaL_optstring(L, 3, []);
if (s.length + sep.length < s.length || s.length + sep.length > MAXSIZE / n) /* may overflow? */
return lauxlib.luaL_error(L, lua.to_luastring("resulting string too large", true));
let r = [];
for (let i = 0; i < n - 1; i++)
r = r.concat(s.concat(sep));
r = r.concat(s);
lua.lua_pushstring(L, n > 0 ? r : []);
return 1;
};
const str_byte = function(L) {
let s = lauxlib.luaL_checkstring(L, 1);
let l = s.length;
let posi = posrelat(lauxlib.luaL_optinteger(L, 2, 1), l);
let pose = posrelat(lauxlib.luaL_optinteger(L, 3, posi), l);
if (posi < 1) posi = 1;
if (pose > l) pose = l;
if (posi > pose) return 0; /* empty interval; return no values */
if (pose - posi >= llimit.MAX_INT) /* arithmetic overflow? */
return lauxlib.luaL_error(L, lua.to_luastring("string slice too long", true));
let n = (pose - posi) + 1;
lauxlib.luaL_checkstack(L, n, lua.to_luastring("string slice too long", true));
for (let i = 0; i < n; i++)
lua.lua_pushinteger(L, s[posi + i - 1]);
return n;
};
const str_packsize = function(L) {
let h = new Header(L);
let fmt = {
s: lauxlib.luaL_checkstring(L, 1),
off: 0
};
let totalsize = 0; /* accumulate total size of result */
while (fmt.off < fmt.s.length) {
let details = getdetails(h, totalsize, fmt);
let opt = details.opt;
let size = details.size;
let ntoalign = details.ntoalign;
size += ntoalign; /* total space used by option */
lauxlib.luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, lua.to_luastring("format result too large", true));
totalsize += size;
switch (opt) {
case KOption.Kstring: /* strings with length count */
case KOption.Kzstr: /* zero-terminated string */
lauxlib.luaL_argerror(L, 1, lua.to_luastring("variable-length format", true));
/* call never return, but to avoid warnings: *//* fall through */
default: break;
}
}
lua.lua_pushinteger(L, totalsize);
return 1;
};
/*
** Unpack an integer with 'size' bytes and 'islittle' endianness.
** If size is smaller than the size of a Lua integer and integer
** is signed, must do sign extension (propagating the sign to the
** higher bits); if size is larger than the size of a Lua integer,
** it must check the unread bytes to see whether they do not cause an
** overflow.
*/
const unpackint = function(L, str, islittle, size, issigned) {
let res = 0;
let limit = size <= SZINT ? size : SZINT;
for (let i = limit - 1; i >= 0; i--) {
res <<= NB;
res |= str[islittle ? i : size - 1 - i];
}
if (size < SZINT) { /* real size smaller than lua_Integer? */
if (issigned) { /* needs sign extension? */
let mask = 1 << (size * NB - 1);
res = ((res ^ mask) - mask); /* do sign extension */
}
} else if (size > SZINT) { /* must check unread bytes */
let mask = !issigned || res >= 0 ? 0 : MC;
for (let i = limit; i < size; i++) {
if (str[islittle ? i : size - 1 - i] !== mask)
lauxlib.luaL_error(L, lua.to_luastring("%d-byte integer does not fit into Lua Integer"), size);
}
}
return res;
};
const unpacknum = function(L, b, islittle, size) {
assert(b.length >= size);
let dv = new DataView(new ArrayBuffer(size));
for (let i = 0; i < size; i++)
dv.setUint8(i, b[i], islittle);
if (size == 4) return dv.getFloat32(0, islittle);
else return dv.getFloat64(0, islittle);
};
const str_unpack = function(L) {
let h = new Header(L);
let fmt = {
s: lauxlib.luaL_checkstring(L, 1),
off: 0
};
let data = lauxlib.luaL_checkstring(L, 2);
let ld = data.length;
let pos = posrelat(lauxlib.luaL_optinteger(L, 3, 1), ld) - 1;
let n = 0; /* number of results */
lauxlib.luaL_argcheck(L, pos <= ld && pos >= 0, 3, lua.to_luastring("initial position out of string", true));
while (fmt.off < fmt.s.length) {
let details = getdetails(h, pos, fmt);
let opt = details.opt;
let size = details.size;
let ntoalign = details.ntoalign;
if (/*ntoalign + size > ~pos ||*/ pos + ntoalign + size > ld)
lauxlib.luaL_argerror(L, 2, lua.to_luastring("data string too short", true));
pos += ntoalign; /* skip alignment */
/* stack space for item + next position */
lauxlib.luaL_checkstack(L, 2, lua.to_luastring("too many results", true));
n++;
switch (opt) {
case KOption.Kint:
case KOption.Kuint: {
let res = unpackint(L, data.slice(pos), h.islittle, size, opt === KOption.Kint);
lua.lua_pushinteger(L, res);
break;
}
case KOption.Kfloat: {
let res = unpacknum(L, data.slice(pos), h.islittle, size);
lua.lua_pushnumber(L, res);
break;
}
case KOption.Kchar: {
lua.lua_pushstring(L, data.slice(pos, pos + size));
break;
}
case KOption.Kstring: {
let len = unpackint(L, data.slice(pos), h.islittle, size, 0);
lauxlib.luaL_argcheck(L, pos + len + size <= ld, 2, lua.to_luastring("data string too short", true));
lua.lua_pushstring(L, data.slice(pos + size, pos + size + len));
pos += len; /* skip string */
break;
}
case KOption.Kzstr: {
let len = data.slice(pos).indexOf(0);
lua.lua_pushstring(L, data.slice(pos, pos + len));
pos += len + 1; /* skip string plus final '\0' */
break;
}
case KOption.Kpaddalign: case KOption.Kpadding: case KOption.Knop:
n--; /* undo increment */
break;
}
pos += size;
}
lua.lua_pushinteger(L, pos + 1); /* next position */
return n + 1;
};
const CAP_UNFINISHED = -1;
const CAP_POSITION = -2;
const MAXCCALLS = 200;
const SPECIALS = ["^".charCodeAt(0), "$".charCodeAt(0), "*".charCodeAt(0), "+".charCodeAt(0), "?".charCodeAt(0), ".".charCodeAt(0), "(".charCodeAt(0), "[".charCodeAt(0), "%".charCodeAt(0), "-".charCodeAt(0)];
class MatchState {
constructor(L) {
this.src = null; /* unmodified source string */
this.src_init = null; /* init of source string */
this.src_end = null; /* end ('\0') of source string */
this.p = null; /* unmodified pattern string */
this.p_end = null; /* end ('\0') of pattern */
this.L = L;
this.matchdepth = NaN; /* control for recursive depth */
this.level = NaN; /* total number of captures (finished or unfinished) */
this.capture = [];
}
}
const check_capture = function(ms, l) {
l = l - '1'.charCodeAt(0);
if (l < 0 || l >= ms.level || ms.capture[l].len === CAP_UNFINISHED)
return lauxlib.luaL_error(ms.L, lua.to_luastring("invalid capture index %%%d"), l + 1);
return l;
};
const capture_to_close = function(ms) {
let level = ms.level;
for (level--; level >= 0; level--)
if (ms.capture[level].len === CAP_UNFINISHED) return level;
return lauxlib.luaL_error(ms.L, lua.to_luastring("invalid pattern capture"));
};
const classend = function(ms, p) {
switch(ms.p[p++]) {
case L_ESC: {
if (p === ms.p_end)
lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (ends with '%%')"));
return p + 1;
}
case '['.charCodeAt(0): {
if (ms.p[p] === '^'.charCodeAt(0)) p++;
do { /* look for a ']' */
if (p === ms.p_end)
lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing ']')"));
if (ms.p[p++] === L_ESC && p < ms.p_end)
p++; /* skip escapes (e.g. '%]') */
} while (ms.p[p] !== ']'.charCodeAt(0));
return p + 1;
}
default: {
return p;
}
}
};
const match_class = function(c, cl) {
let res;
switch (String.fromCharCode(cl).toLowerCase().charCodeAt(0)) {
case 'a'.charCodeAt(0) : res = isalpha(c); break;
case 'c'.charCodeAt(0) : res = iscntrl(c); break;
case 'd'.charCodeAt(0) : res = isdigit(c); break;
case 'g'.charCodeAt(0) : res = isgraph(c); break;
case 'l'.charCodeAt(0) : res = islower(c); break;
case 'p'.charCodeAt(0) : res = ispunct(c); break;
case 's'.charCodeAt(0) : res = isspace(c); break;
case 'u'.charCodeAt(0) : res = isupper(c); break;
case 'w'.charCodeAt(0) : res = isalnum(c); break;
case 'x'.charCodeAt(0) : res = isxdigit(c); break;
case 'z'.charCodeAt(0) : res = (c === 0); break; /* deprecated option */
default: return (cl === c);
}
return (islower(cl) ? res : !res);
};
const matchbracketclass = function(ms, c, p, ec) {
let sig = true;
if (ms.p[p + 1] === '^'.charCodeAt(0)) {
sig = false;
p++; /* skip the '^' */
}
while (++p < ec) {
if (ms.p[p] === L_ESC) {
p++;
if (match_class(c, ms.p[p]))
return sig;
} else if (ms.p[p + 1] === '-'.charCodeAt(0) && p + 2 < ec) {
p += 2;
if (ms.p[p - 2] <= c && c <= ms.p[p])
return sig;
} else if (ms.p[p] === c) return sig;
}
return !sig;
};
const singlematch = function(ms, s, p, ep) {
if (s >= ms.src_end)
return false;
else {
let c = ms.src[s];
switch (ms.p[p]) {
case '.'.charCodeAt(0): return true; /* matches any char */
case L_ESC: return match_class(c, ms.p[p + 1]);
case '['.charCodeAt(0): return matchbracketclass(ms, c, p, ep - 1);
default: return ms.p[p] === c;
}
}
};
const matchbalance = function(ms, s, p) {
if (p >= ms.p_end - 1)
lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing arguments to '%%b'"));
if (ms.src[s] !== ms.p[p])
return null;
else {
let b = ms.p[p];
let e = ms.p[p + 1];
let cont = 1;
while (++s < ms.src_end) {
if (ms.src[s] === e) {
if (--cont === 0) return s + 1;
}
else if (ms.src[s] === b) cont++;
}
}
return null; /* string ends out of balance */
};
const max_expand = function(ms, s, p, ep) {
let i = 0; /* counts maximum expand for item */
while (singlematch(ms, s + i, p, ep))
i++;
/* keeps trying to match with the maximum repetitions */
while (i >= 0) {
let res = match(ms, s + i, ep + 1);
if (res) return res;
i--; /* else didn't match; reduce 1 repetition to try again */
}
return null;
};
const min_expand = function(ms, s, p, ep) {
for (;;) {
let res = match(ms, s, ep + 1);
if (res !== null)
return res;
else if (singlematch(ms, s, p, ep))
s++; /* try with one more repetition */
else return null;
}
};
const start_capture = function(ms, s, p, what) {
let level = ms.level;
if (level >= LUA_MAXCAPTURES) lauxlib.luaL_error(ms.L, lua.to_luastring("too many captures", true));
ms.capture[level] = ms.capture[level] ? ms.capture[level] : {};
ms.capture[level].init = s;
ms.capture[level].len = what;
ms.level = level + 1;
let res;
if ((res = match(ms, s, p)) === null) /* match failed? */
ms.level--; /* undo capture */
return res;
};
const end_capture = function(ms, s, p) {
let l = capture_to_close(ms);
ms.capture[l].len = s - ms.capture[l].init; /* close capture */
let res;
if ((res = match(ms, s, p)) === null) /* match failed? */
ms.capture[l].len = CAP_UNFINISHED; /* undo capture */
return res;
};
/* Compare the elements of arrays 'a' and 'b' to see if they contain the same elements */
const array_cmp = function(a, ai, b, bi, len) {
let aj = ai+len;
for (; ai < aj; ai++, bi++) {
if (a[ai] !== b[bi])
return false;
}
return true;
};
const match_capture = function(ms, s, l) {
l = check_capture(ms, l);
let len = ms.capture[l].len;
if ((ms.src_end-s) >= len && array_cmp(ms.src, ms.capture[l].init, ms.src, s, len))
return s+len;
else return null;
};
const match = function(ms, s, p) {
let gotodefault = false;
let gotoinit = true;
if (ms.matchdepth-- === 0)
lauxlib.luaL_error(ms.L, lua.to_luastring("pattern too complex", true));
while (gotoinit || gotodefault) {
gotoinit = false;
if (p !== ms.p_end) { /* end of pattern? */
switch (gotodefault ? 'x'.charCodeAt(0) : ms.p[p]) {
case '('.charCodeAt(0): { /* start capture */
if (ms.p[p + 1] === ')'.charCodeAt(0)) /* position capture? */
s = start_capture(ms, s, p + 2, CAP_POSITION);
else
s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
break;
}
case ')'.charCodeAt(0): { /* end capture */
s = end_capture(ms, s, p + 1);
break;
}
case '$'.charCodeAt(0): {
if (p + 1 !== ms.p_end) { /* is the '$' the last char in pattern? */
gotodefault = true; /* no; go to default */
break;
}
s = ms.src.slice(s).length === 0 ? s : null; /* check end of string */
break;
}
case L_ESC: { /* escaped sequences not in the format class[*+?-]? */
switch (ms.p[p + 1]) {
case 'b'.charCodeAt(0): { /* balanced string? */
s = matchbalance(ms, s, p + 2);
if (s !== null) {
p += 4;
gotoinit = true;
}
break;
}
case 'f'.charCodeAt(0): { /* frontier? */
p += 2;
if (ms.p[p] !== '['.charCodeAt(0))
lauxlib.luaL_error(ms.L, lua.to_luastring("missing '[' after '%%f' in pattern"));
let ep = classend(ms, p); /* points to what is next */
let previous = s === ms.src_init ? 0 : ms.src[s-1];
if (!matchbracketclass(ms, previous, p, ep - 1) && matchbracketclass(ms, (s===ms.src_end)?0:ms.src[s], p, ep - 1)) {
p = ep; gotoinit = true; break;
}
s = null; /* match failed */
break;
}
case '0'.charCodeAt(0): case '1'.charCodeAt(0): case '2'.charCodeAt(0): case '3'.charCodeAt(0):
case '4'.charCodeAt(0): case '5'.charCodeAt(0): case '6'.charCodeAt(0): case '7'.charCodeAt(0):
case '8'.charCodeAt(0): case '9'.charCodeAt(0): { /* capture results (%0-%9)? */
s = match_capture(ms, s, ms.p[p + 1]);
if (s !== null) {
p += 2; gotoinit = true;
}
break;
}
default: gotodefault = true;
}
break;
}
default: { /* pattern class plus optional suffix */
gotodefault = false;
let ep = classend(ms, p); /* points to optional suffix */
/* does not match at least once? */
if (!singlematch(ms, s, p, ep)) {
if (ms.p[ep] === '*'.charCodeAt(0) || ms.p[ep] === '?'.charCodeAt(0) || ms.p[ep] === '-'.charCodeAt(0)) { /* accept empty? */
p = ep + 1; gotoinit = true; break;
} else /* '+' or no suffix */
s = null; /* fail */
} else { /* matched once */
switch (ms.p[ep]) { /* handle optional suffix */
case '?'.charCodeAt(0): { /* optional */
let res;
if ((res = match(ms, s + 1, ep + 1)) !== null)
s = res;
else {
p = ep + 1; gotoinit = true;
}
break;
}
case '+'.charCodeAt(0): /* 1 or more repetitions */
s++; /* 1 match already done */
/* fall through */
case '*'.charCodeAt(0): /* 0 or more repetitions */
s = max_expand(ms, s, p, ep);
break;
case '-'.charCodeAt(0): /* 0 or more repetitions (minimum) */
s = min_expand(ms, s, p, ep);
break;
default: /* no suffix */
s++; p = ep; gotoinit = true;
}
}
break;
}
}
}
}
ms.matchdepth++;
return s;
};
const push_onecapture = function(ms, i, s, e) {
if (i >= ms.level) {
if (i === 0)
lua.lua_pushlstring(ms.L, ms.src.slice(s, e), e - s); /* add whole match */
else
lauxlib.luaL_error(ms.L, lua.to_luastring("invalid capture index %%%d"), i + 1);
} else {
let l = ms.capture[i].len;
if (l === CAP_UNFINISHED) lauxlib.luaL_error(ms.L, lua.to_luastring("unfinished capture", true));
if (l === CAP_POSITION)
lua.lua_pushinteger(ms.L, ms.capture[i].init - ms.src_init + 1);
else
lua.lua_pushlstring(ms.L, ms.src.slice(ms.capture[i].init), l);
}
};
const push_captures = function(ms, s, e) {
let nlevels = ms.level === 0 && ms.src.slice(s) ? 1 : ms.level;
lauxlib.luaL_checkstack(ms.L, nlevels, lua.to_luastring("too many catpures", true));
for (let i = 0; i < nlevels; i++)
push_onecapture(ms, i, s, e);
return nlevels; /* number of strings pushed */
};
const nospecials = function(p, l) {
let upto = 0;
do {
let special = false;
let supto = p.slice(upto);
for (let i = 0; i < SPECIALS.length; i++) {
if (supto.indexOf(SPECIALS[i]) > -1) {
special = true;
break;
}
}
if (special)
return false; /* pattern has a special character */
upto = upto + 1; /* may have more after \0 */
} while (upto <= l);
return true; /* no special chars found */
};
const prepstate = function(ms, L, s, ls, p, lp) {
ms.L = L;
ms.matchdepth = MAXCCALLS;
ms.src = s;
ms.src_init = 0;
ms.src_end = ls;
ms.p = p;
ms.p_end = lp;
};
const reprepstate = function(ms) {
ms.level = 0;
assert(ms.matchdepth === MAXCCALLS);
};
const find_subarray = function(arr, subarr, from_index) {
var i = from_index >>> 0,
sl = subarr.length,
l = arr.length + 1 - sl;
loop: for (; i < l; i++) {
for (let j = 0; j < sl; j++)
if (arr[i+j] !== subarr[j])
continue loop;
return i;
}
return -1;
};
const str_find_aux = function(L, find) {
let s = lauxlib.luaL_checkstring(L, 1);
let p = lauxlib.luaL_checkstring(L, 2);
let ls = s.length;
let lp = p.length;
let init = posrelat(lauxlib.luaL_optinteger(L, 3, 1), ls);
if (init < 1) init = 1;
else if (init > ls + 1) { /* start after string's end? */
lua.lua_pushnil(L); /* cannot find anything */
return 1;
}
/* explicit request or no special characters? */
if (find && (lua.lua_toboolean(L, 4) || nospecials(p, lp))) {
/* do a plain search */
let f = find_subarray(s.slice(init - 1), p, 0);
if (f > -1) {
lua.lua_pushinteger(L, init + f);
lua.lua_pushinteger(L, init + f + lp - 1);
return 2;
}
} else {
let ms = new MatchState(L);
let s1 = init - 1;
let anchor = p[0] === '^'.charCodeAt(0);
if (anchor) {
p = p.slice(1); lp--; /* skip anchor character */
}
prepstate(ms, L, s, ls, p, lp);
do {
let res;
reprepstate(ms);
if ((res = match(ms, s1, 0)) !== null) {
if (find) {
lua.lua_pushinteger(L, s1 + 1); /* start */
lua.lua_pushinteger(L, res); /* end */
return push_captures(ms, null, 0) + 2;
} else
return push_captures(ms, s1, res);
}
} while (s1++ < ms.src_end && !anchor);
}
lua.lua_pushnil(L); /* not found */
return 1;
};
const str_find = function(L) {
return str_find_aux(L, 1);
};
const str_match = function(L) {
return str_find_aux(L, 0);
};
/* state for 'gmatch' */
class GMatchState {
constructor() {
this.src = NaN; /* current position */
this.p = NaN; /* pattern */
this.lastmatch = NaN; /* end of last match */
this.ms = new MatchState(); /* match state */
}
}
const gmatch_aux = function(L) {
let gm = lua.lua_touserdata(L, lua.lua_upvalueindex(3));
gm.ms.L = L;
for (let src = gm.src; src <= gm.ms.src_end; src++) {
reprepstate(gm.ms);
let e;
if ((e = match(gm.ms, src, gm.p)) !== null && e !== gm.lastmatch) {
gm.src = gm.lastmatch = e;
return push_captures(gm.ms, src, e);
}
}
return 0; /* not found */
};
const str_gmatch = function(L) {
let s = lauxlib.luaL_checkstring(L, 1);
let p = lauxlib.luaL_checkstring(L, 2);
let ls = s.length;
let lp = p.length;
lua.lua_settop(L, 2); /* keep them on closure to avoid being collected */
let gm = new GMatchState();
lua.lua_pushlightuserdata(L, gm);
prepstate(gm.ms, L, s, ls, p, lp);
gm.src = 0;
gm.p = 0;
gm.lastmatch = null;
lua.lua_pushcclosure(L, gmatch_aux, 3);
return 1;
};
const add_s = function(ms, b, s, e) {
let L = ms.L;
let news = lua.lua_tostring(L, 3);
let l = news.length;
for (let i = 0; i < l; i++) {
if (news[i] !== L_ESC)
lauxlib.luaL_addchar(b, news[i]);
else {
i++; /* skip ESC */
if (!isdigit(news[i])) {
if (news[i] !== L_ESC)
lauxlib.luaL_error(L, lua.to_luastring("invalid use of '%c' in replacement string"), L_ESC);
lauxlib.luaL_addchar(b, news[i]);
} else if (news[i] === '0'.charCodeAt(0))
lauxlib.luaL_addlstring(b, ms.src.slice(s), e - s);
else {
push_onecapture(ms, news[i] - '1'.charCodeAt(0), s, e);
lauxlib.luaL_tolstring(L, -1);
lua.lua_remove(L, -2); /* remove original value */
lauxlib.luaL_addvalue(b); /* add capture to accumulated result */
}
}
}
};
const add_value = function(ms, b, s, e, tr) {
let L = ms.L;
switch (tr) {
case lua.LUA_TFUNCTION: {
lua.lua_pushvalue(L, 3);
let n = push_captures(ms, s, e);
lua.lua_call(L, n, 1);
break;
}
case lua.LUA_TTABLE: {
push_onecapture(ms, 0, s, e);
lua.lua_gettable(L, 3);
break;
}
default: { /* LUA_TNUMBER or LUA_TSTRING */
add_s(ms, b, s, e);
return;
}
}
if (!lua.lua_toboolean(L, -1)) { /* nil or false? */
lua.lua_pop(L, 1);
lua.lua_pushlstring(L, ms.src.slice(s, e), e - s); /* keep original text */
} else if (!lua.lua_isstring(L, -1))
lauxlib.luaL_error(L, lua.to_luastring("invalid replacement value (a %s)"), lauxlib.luaL_typename(L, -1));
lauxlib.luaL_addvalue(b); /* add result to accumulator */
};
const str_gsub = function(L) {
let src = lauxlib.luaL_checkstring(L, 1); /* subject */
let srcl = src.length;
let p = lauxlib.luaL_checkstring(L, 2); /* pattern */
let lp = p.length;
let lastmatch = null; /* end of last match */
let tr = lua.lua_type(L, 3); /* replacement type */
let max_s = lauxlib.luaL_optinteger(L, 4, srcl + 1); /* max replacements */
let anchor = p[0] === '^'.charCodeAt(0);
let n = 0; /* replacement count */
let ms = new MatchState(L);
let b = new lauxlib.luaL_Buffer();
lauxlib.luaL_argcheck(L, tr === lua.LUA_TNUMBER || tr === lua.LUA_TSTRING || tr === lua.LUA_TFUNCTION || tr === lua.LUA_TTABLE, 3,
lua.to_luastring("string/function/table expected", true));
lauxlib.luaL_buffinit(L, b);
if (anchor) {
p = p.slice(1); lp--; /* skip anchor character */
}
prepstate(ms, L, src, srcl, p, lp);
src = 0; p = 0;
while (n < max_s) {
let e;
reprepstate(ms);
if ((e = match(ms, src, p)) !== null && e !== lastmatch) { /* match? */
n++;
add_value(ms, b, src, e, tr); /* add replacement to buffer */
src = lastmatch = e;
} else if (src < ms.src_end) /* otherwise, skip one character */
lauxlib.luaL_addchar(b, ms.src[src++]);
else break; /* end of subject */
if (anchor) break;
}
lauxlib.luaL_addlstring(b, ms.src.slice(src), ms.src_end - src);
lauxlib.luaL_pushresult(b);
lua.lua_pushinteger(L, n); /* number of substitutions */
return 2;
};
const strlib = {
"byte": str_byte,
"char": str_char,
"dump": str_dump,
"find": str_find,
"format": str_format,
"gmatch": str_gmatch,
"gsub": str_gsub,
"len": str_len,
"lower": str_lower,
"match": str_match,
"pack": str_pack,
"packsize": str_packsize,
"rep": str_rep,
"reverse": str_reverse,
"sub": str_sub,
"unpack": str_unpack,
"upper": str_upper
};
const createmetatable = function(L) {
lua.lua_createtable(L, 0, 1); /* table to be metatable for strings */
lua.lua_pushliteral(L, ""); /* dummy string */
lua.lua_pushvalue(L, -2); /* copy table */
lua.lua_setmetatable(L, -2); /* set table as metatable for strings */
lua.lua_pop(L, 1); /* pop dummy string */
lua.lua_pushvalue(L, -2); /* get string library */
lua.lua_setfield(L, -2, lua.to_luastring("__index", true)); /* metatable.__index = string */
lua.lua_pop(L, 1); /* pop metatable */
};
const luaopen_string = function(L) {
lauxlib.luaL_newlib(L, strlib);
createmetatable(L);
return 1;
};
module.exports.luaopen_string = luaopen_string;
/***/ }),
/* 48 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const lua = __webpack_require__(3);
const lauxlib = __webpack_require__(9);
const llimit = __webpack_require__(8);
/*
** Operations that an object must define to mimic a table
** (some functions only need some of them)
*/
const TAB_R = 1; /* read */
const TAB_W = 2; /* write */
const TAB_L = 4; /* length */
const TAB_RW = (TAB_R | TAB_W); /* read/write */
const checkfield = function(L, key, n) {
lua.lua_pushstring(L, key);
return lua.lua_rawget(L, -n) !== lua.LUA_TNIL;
};
/*
** Check that 'arg' either is a table or can behave like one (that is,
** has a metatable with the required metamethods)
*/
const checktab = function(L, arg, what) {
if (lua.lua_type(L, arg) !== lua.LUA_TTABLE) { /* is it not a table? */
let n = 1;
if (lua.lua_getmetatable(L, arg) && /* must have metatable */
(!(what & TAB_R) || checkfield(L, lua.to_luastring("__index", true), ++n)) &&
(!(what & TAB_W) || checkfield(L, lua.to_luastring("__newindex", true), ++n)) &&
(!(what & TAB_L) || checkfield(L, lua.to_luastring("__len", true), ++n))) {
lua.lua_pop(L, n); /* pop metatable and tested metamethods */
}
else
lauxlib.luaL_checktype(L, arg, lua.LUA_TTABLE); /* force an error */
}
};
const aux_getn = function(L, n, w) {
checktab(L, n, w | TAB_L);
return lauxlib.luaL_len(L, n);
};
const addfield = function(L, b, i) {
lua.lua_geti(L, 1, i);
if (!lua.lua_isstring(L, -1))
lauxlib.luaL_error(L, lua.to_luastring("invalid value (%s) at index %d in table for 'concat'"),
lauxlib.luaL_typename(L, -1), i);
lauxlib.luaL_addvalue(b);
};
const tinsert = function(L) {
let e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */
let pos;
switch (lua.lua_gettop(L)) {
case 2:
pos = e;
break;
case 3: {
pos = lauxlib.luaL_checkinteger(L, 2); /* 2nd argument is the position */
lauxlib.luaL_argcheck(L, 1 <= pos && pos <= e, 2, lua.to_luastring("position out of bounds", true));
for (let i = e; i > pos; i--) { /* move up elements */
lua.lua_geti(L, 1, i - 1);
lua.lua_seti(L, 1, i); /* t[i] = t[i - 1] */
}
break;
}
default: {
return lauxlib.luaL_error(L, lua.to_luastring("wrong number of arguments to 'insert'", true));
}
}
lua.lua_seti(L, 1, pos); /* t[pos] = v */
return 0;
};
const tremove = function(L) {
let size = aux_getn(L, 1, TAB_RW);
let pos = lauxlib.luaL_optinteger(L, 2, size);
if (pos !== size) /* validate 'pos' if given */
lauxlib.luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, lua.to_luastring("position out of bounds", true));
lua.lua_geti(L, 1, pos); /* result = t[pos] */
for (; pos < size; pos++) {
lua.lua_geti(L, 1, pos + 1);
lua.lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */
}
lua.lua_pushnil(L);
lua.lua_seti(L, 1, pos); /* t[pos] = nil */
return 1;
};
/*
** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever
** possible, copy in increasing order, which is better for rehashing.
** "possible" means destination after original range, or smaller
** than origin, or copying to another table.
*/
const tmove = function(L) {
let f = lauxlib.luaL_checkinteger(L, 2);
let e = lauxlib.luaL_checkinteger(L, 3);
let t = lauxlib.luaL_checkinteger(L, 4);
let tt = !lua.lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
checktab(L, 1, TAB_R);
checktab(L, tt, TAB_W);
if (e >= f) { /* otherwise, nothing to move */
lauxlib.luaL_argcheck(L, f > 0 || e < llimit.LUA_MAXINTEGER + f, 3, lua.to_luastring("too many elements to move", true));
let n = e - f + 1; /* number of elements to move */
lauxlib.luaL_argcheck(L, t <= llimit.LUA_MAXINTEGER - n + 1, 4, lua.to_luastring("destination wrap around", true));
if (t > e || t <= f || (tt !== 1 && lua.lua_compare(L, 1, tt, lua.LUA_OPEQ) !== 1)) {
for (let i = 0; i < n; i++) {
lua.lua_geti(L, 1, f + i);
lua.lua_seti(L, tt, t + i);
}
} else {
for (let i = n - 1; i >= 0; i--) {
lua.lua_geti(L, 1, f + i);
lua.lua_seti(L, tt, t + i);
}
}
}
lua.lua_pushvalue(L, tt); /* return destination table */
return 1;
};
const tconcat = function(L) {
let last = aux_getn(L, 1, TAB_R);
let sep = lauxlib.luaL_optlstring(L, 2, []);
let i = lauxlib.luaL_optinteger(L, 3, 1);
last = lauxlib.luaL_optinteger(L, 4, last);
let b = new lauxlib.luaL_Buffer();
lauxlib.luaL_buffinit(L, b);
for (; i < last; i++) {
addfield(L, b, i);
lauxlib.luaL_addlstring(b, sep);
}
if (i === last)
addfield(L, b, i);
lauxlib.luaL_pushresult(b);
return 1;
};
const pack = function(L) {
let n = lua.lua_gettop(L); /* number of elements to pack */
lua.lua_createtable(L, n, 1); /* create result table */
lua.lua_insert(L, 1); /* put it at index 1 */
for (let i = n; i >= 1; i--) /* assign elements */
lua.lua_seti(L, 1, i);
lua.lua_pushinteger(L, n);
lua.lua_setfield(L, 1, ["n".charCodeAt(0)]); /* t.n = number of elements */
return 1; /* return table */
};
const unpack = function(L) {
let i = lauxlib.luaL_optinteger(L, 2, 1);
let e = lauxlib.luaL_opt(L, lauxlib.luaL_checkinteger, 3, lauxlib.luaL_len(L, 1));
if (i > e) return 0; /* empty range */
let n = e - i; /* number of elements minus 1 (avoid overflows) */
if (n >= llimit.MAX_INT || !lua.lua_checkstack(L, ++n))
return lauxlib.luaL_error(L, lua.to_luastring("too many results to unpack", true));
for (; i < e; i++) /* push arg[i..e - 1] (to avoid overflows) */
lua.lua_geti(L, 1, i);
lua.lua_geti(L, 1, e); /* push last element */
return n;
};
const l_randomizePivot = function() {
return Math.floor(Math.random()*1<<32);
};
const RANLIMIT = 100;
const set2 = function(L, i, j) {
lua.lua_seti(L, 1, i);
lua.lua_seti(L, 1, j);
};
const sort_comp = function(L, a, b) {
if (lua.lua_isnil(L, 2)) /* no function? */
return lua.lua_compare(L, a, b, lua.LUA_OPLT); /* a < b */
else { /* function */
lua.lua_pushvalue(L, 2); /* push function */
lua.lua_pushvalue(L, a-1); /* -1 to compensate function */
lua.lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */
lua.lua_call(L, 2, 1); /* call function */
let res = lua.lua_toboolean(L, -1); /* get result */
lua.lua_pop(L, 1); /* pop result */
return res;
}
};
const partition = function(L, lo, up) {
let i = lo; /* will be incremented before first use */
let j = up - 1; /* will be decremented before first use */
/* loop invariant: a[lo .. i] <= P <= a[j .. up] */
for (;;) {
/* next loop: repeat ++i while a[i] < P */
while (lua.lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) {
if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */
lauxlib.luaL_error(L, lua.to_luastring("invalid order function for sorting"));
lua.lua_pop(L, 1); /* remove a[i] */
}
/* after the loop, a[i] >= P and a[lo .. i - 1] < P */
/* next loop: repeat --j while P < a[j] */
while (lua.lua_geti(L, 1, --j), sort_comp(L, -3, -1)) {
if (j < i) /* j < i but a[j] > P ?? */
lauxlib.luaL_error(L, lua.to_luastring("invalid order function for sorting"));
lua.lua_pop(L, 1); /* remove a[j] */
}
/* after the loop, a[j] <= P and a[j + 1 .. up] >= P */
if (j < i) { /* no elements out of place? */
/* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */
lua.lua_pop(L, 1); /* pop a[j] */
/* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */
set2(L, up - 1, i);
return i;
}
/* otherwise, swap a[i] - a[j] to restore invariant and repeat */
set2(L, i, j);
}
};
const choosePivot = function(lo, up, rnd) {
let r4 = Math.floor((up - lo) / 4); /* range/4 */
let p = rnd % (r4 * 2) + (lo + r4);
assert(lo + r4 <= p && p <= up - r4);
return p;
};
const auxsort = function(L, lo, up, rnd) {
while (lo < up) { /* loop for tail recursion */
/* sort elements 'lo', 'p', and 'up' */
lua.lua_geti(L, 1, lo);
lua.lua_geti(L, 1, up);
if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */
set2(L, lo, up); /* swap a[lo] - a[up] */
else
lua.lua_pop(L, 2); /* remove both values */
if (up - lo == 1) /* only 2 elements? */
return; /* already sorted */
let p; /* Pivot index */
if (up - lo < RANLIMIT || rnd === 0) /* small interval or no randomize? */
p = Math.floor((lo + up)/2); /* middle element is a good pivot */
else /* for larger intervals, it is worth a random pivot */
p = choosePivot(lo, up, rnd);
lua.lua_geti(L, 1, p);
lua.lua_geti(L, 1, lo);
if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */
set2(L, p, lo); /* swap a[p] - a[lo] */
else {
lua.lua_pop(L, 1); /* remove a[lo] */
lua.lua_geti(L, 1, up);
if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */
set2(L, p, up); /* swap a[up] - a[p] */
else
lua.lua_pop(L, 2);
}
if (up - lo == 2) /* only 3 elements? */
return; /* already sorted */
lua.lua_geti(L, 1, p); /* get middle element (Pivot) */
lua.lua_pushvalue(L, -1); /* push Pivot */
lua.lua_geti(L, 1, up - 1); /* push a[up - 1] */
set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */
p = partition(L, lo, up);
let n;
/* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */
if (p - lo < up - p) { /* lower interval is smaller? */
auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */
n = p - lo; /* size of smaller interval */
lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */
} else {
auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */
n = up - p; /* size of smaller interval */
up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */
}
if ((up - lo) / 128 > n) /* partition too imbalanced? */
rnd = l_randomizePivot(); /* try a new randomization */
} /* tail call auxsort(L, lo, up, rnd) */
};
const sort = function(L) {
let n = aux_getn(L, 1, TAB_RW);
if (n > 1) { /* non-trivial interval? */
lauxlib.luaL_argcheck(L, n < llimit.MAX_INT, 1, lua.to_luastring("array too big", true));
if (!lua.lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
lauxlib.luaL_checktype(L, 2, lua.LUA_TFUNCTION); /* must be a function */
lua.lua_settop(L, 2); /* make sure there are two arguments */
auxsort(L, 1, n, 0);
}
return 0;
};
const tab_funcs = {
"concat": tconcat,
"insert": tinsert,
"move": tmove,
"pack": pack,
"remove": tremove,
"sort": sort,
"unpack": unpack
};
const luaopen_table = function(L) {
lauxlib.luaL_newlib(L, tab_funcs);
return 1;
};
module.exports.luaopen_table = luaopen_table;
/***/ }),
/* 49 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const lua = __webpack_require__(3);
const lauxlib = __webpack_require__(9);
const llimit = __webpack_require__(8);
const MAXUNICODE = 0x10FFFF;
const iscont = function(p) {
let c = p & 0xC0;
return c === 0x80;
};
/* translate a relative string position: negative means back from end */
const u_posrelat = function(pos, len) {
if (pos >= 0) return pos;
else if (0 - pos > len) return 0;
else return len + pos + 1;
};
/*
** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid.
*/
const limits = [0xFF, 0x7F, 0x7FF, 0xFFFF];
const utf8_decode = function(s, pos) {
let c = s[pos];
let res = 0; /* final result */
if (c < 0x80) /* ascii? */
res = c;
else {
let count = 0; /* to count number of continuation bytes */
while (c & 0x40) { /* still have continuation bytes? */
let cc = s[pos + (++count)]; /* read next byte */
if ((cc & 0xC0) !== 0x80) /* not a continuation byte? */
return null; /* invalid byte sequence */
res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */
c <<= 1; /* to test next bit */
}
res |= ((c & 0x7F) << (count * 5)); /* add first byte */
if (count > 3 || res > MAXUNICODE || res <= limits[count])
return null; /* invalid byte sequence */
pos += count; /* skip continuation bytes read */
}
return {
code: res,
pos: pos + 1
};
};
/*
** utf8len(s [, i [, j]]) --> number of characters that start in the
** range [i,j], or nil + current position if 's' is not well formed in
** that interval
*/
const utflen = function(L) {
let n = 0;
let s = lauxlib.luaL_checkstring(L, 1);
let len = s.length;
let posi = u_posrelat(lauxlib.luaL_optinteger(L, 2, 1), len);
let posj = u_posrelat(lauxlib.luaL_optinteger(L, 3, -1), len);
lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= len, 2, lua.to_luastring("initial position out of string"));
lauxlib.luaL_argcheck(L, --posj < len, 3, lua.to_luastring("final position out of string"));
while (posi <= posj) {
let dec = utf8_decode(s, posi);
if (dec === null) { /* conversion error? */
lua.lua_pushnil(L); /* return nil ... */
lua.lua_pushinteger(L, posi + 1); /* ... and current position */
return 2;
}
posi = dec.pos;
n++;
}
lua.lua_pushinteger(L, n);
return 1;
};
const pushutfchar = function(L, arg) {
let code = lauxlib.luaL_checkinteger(L, arg);
lauxlib.luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, lua.to_luastring("value out of range", true));
lua.lua_pushstring(L, lua.to_luastring(String.fromCodePoint(code)));
};
/*
** utfchar(n1, n2, ...) -> char(n1)..char(n2)...
*/
const utfchar = function(L) {
let n = lua.lua_gettop(L); /* number of arguments */
if (n === 1) /* optimize common case of single char */
pushutfchar(L, 1);
else {
let b = new lauxlib.luaL_Buffer();
lauxlib.luaL_buffinit(L, b);
for (let i = 1; i <= n; i++) {
pushutfchar(L, i);
lauxlib.luaL_addvalue(b);
}
lauxlib.luaL_pushresult(b);
}
return 1;
};
/*
** offset(s, n, [i]) -> index where n-th character counting from
** position 'i' starts; 0 means character at 'i'.
*/
const byteoffset = function(L) {
let s = lauxlib.luaL_checkstring(L, 1);
let n = lauxlib.luaL_checkinteger(L, 2);
let posi = n >= 0 ? 1 : s.length + 1;
posi = u_posrelat(lauxlib.luaL_optinteger(L, 3, posi), s.length);
lauxlib.luaL_argcheck(L, 1 <= posi && --posi <= s.length, 3, lua.to_luastring("position out of range", true));
if (n === 0) {
/* find beginning of current byte sequence */
while (posi > 0 && iscont(s[posi])) posi--;
} else {
if (iscont(s[posi]))
lauxlib.luaL_error(L, lua.to_luastring("initial position is a continuation byte", true));
if (n < 0) {
while (n < 0 && posi > 0) { /* move back */
do { /* find beginning of previous character */
posi--;
} while (posi > 0 && iscont(s[posi]));
n++;
}
} else {
n--; /* do not move for 1st character */
while (n > 0 && posi < s.length) {
do { /* find beginning of next character */
posi++;
} while (iscont(s[posi])); /* (cannot pass final '\0') */
n--;
}
}
}
if (n === 0) /* did it find given character? */
lua.lua_pushinteger(L, posi + 1);
else /* no such character */
lua.lua_pushnil(L);
return 1;
};
/*
** codepoint(s, [i, [j]]) -> returns codepoints for all characters
** that start in the range [i,j]
*/
const codepoint = function(L) {
let s = lauxlib.luaL_checkstring(L, 1);
let posi = u_posrelat(lauxlib.luaL_optinteger(L, 2, 1), s.length);
let pose = u_posrelat(lauxlib.luaL_optinteger(L, 3, posi), s.length);
lauxlib.luaL_argcheck(L, posi >= 1, 2, lua.to_luastring("out of range", true));
lauxlib.luaL_argcheck(L, pose <= s.length, 3, lua.to_luastring("out of range", true));
if (posi > pose) return 0; /* empty interval; return no values */
if (pose - posi >= llimit.MAX_INT)
return lauxlib.luaL_error(L, lua.to_luastring("string slice too long", true));
let n = (pose - posi) + 1;
lauxlib.luaL_checkstack(L, n, lua.to_luastring("string slice too long", true));
n = 0;
for (posi -= 1; posi < pose;) {
let dec = utf8_decode(s, posi);
if (dec === null)
return lauxlib.luaL_error(L, lua.to_luastring("invalid UTF-8 code", true));
lua.lua_pushinteger(L, dec.code);
posi = dec.pos;
n++;
}
return n;
};
const iter_aux = function(L) {
let s = lauxlib.luaL_checkstring(L, 1);
let len = s.length;
let n = lua.lua_tointeger(L, 2) - 1;
if (n < 0) /* first iteration? */
n = 0; /* start from here */
else if (n < len) {
n++; /* skip current byte */
while (iscont(s[n])) n++; /* and its continuations */
}
if (n >= len)
return 0; /* no more codepoints */
else {
let dec = utf8_decode(s, n);
if (dec === null || iscont(s[dec.pos]))
return lauxlib.luaL_error(L, lua.to_luastring("invalid UTF-8 code", true));
lua.lua_pushinteger(L, n + 1);
lua.lua_pushinteger(L, dec.code);
return 2;
}
};
const iter_codes = function(L) {
lauxlib.luaL_checkstring(L, 1);
lua.lua_pushcfunction(L, iter_aux);
lua.lua_pushvalue(L, 1);
lua.lua_pushinteger(L, 0);
return 3;
};
const funcs = {
"char": utfchar,
"codepoint": codepoint,
"codes": iter_codes,
"len": utflen,
"offset": byteoffset
};
/* pattern to match a single UTF-8 character */
const UTF8PATT = [ 91, 0, 45, 127, 194, 45, 244, 93, 91, 128, 45, 191, 93, 42 ];
const luaopen_utf8 = function(L) {
lauxlib.luaL_newlib(L, funcs);
lua.lua_pushstring(L, UTF8PATT);
lua.lua_setfield(L, -2, lua.to_luastring("charpattern", true));
return 1;
};
module.exports.luaopen_utf8 = luaopen_utf8;
/***/ }),
/* 50 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const lua = __webpack_require__(3);
const lauxlib = __webpack_require__(9);
/*
** If L1 != L, L1 can be in any state, and therefore there are no
** guarantees about its stack space; any push in L1 must be
** checked.
*/
const checkstack = function(L, L1, n) {
if (L !== L1 && !lua.lua_checkstack(L1, n))
lauxlib.luaL_error(L, lua.to_luastring("stack overflow", true));
};
const db_getregistry = function(L) {
lua.lua_pushvalue(L, lua.LUA_REGISTRYINDEX);
return 1;
};
const db_getmetatable = function(L) {
lauxlib.luaL_checkany(L, 1);
if (!lua.lua_getmetatable(L, 1)) {
lua.lua_pushnil(L); /* no metatable */
}
return 1;
};
const db_setmetatable = function(L) {
const t = lua.lua_type(L, 2);
lauxlib.luaL_argcheck(L, t == lua.LUA_TNIL || t == lua.LUA_TTABLE, 2, lua.to_luastring("nil or table expected", true));
lua.lua_settop(L, 2);
lua.lua_setmetatable(L, 1);
return 1; /* return 1st argument */
};
const db_getuservalue = function(L) {
if (lua.lua_type(L, 1) !== lua.LUA_TUSERDATA)
lua.lua_pushnil(L);
else
lua.lua_getuservalue(L, 1);
return 1;
};
const db_setuservalue = function(L) {
lauxlib.luaL_checktype(L, 1, lua.LUA_TUSERDATA);
lauxlib.luaL_checkany(L, 2);
lua.lua_settop(L, 2);
lua.lua_setuservalue(L, 1);
return 1;
};
/*
** Auxiliary function used by several library functions: check for
** an optional thread as function's first argument and set 'arg' with
** 1 if this argument is present (so that functions can skip it to
** access their other arguments)
*/
const getthread = function(L) {
if (lua.lua_isthread(L, 1)) {
return {
arg: 1,
thread: lua.lua_tothread(L, 1)
};
} else {
return {
arg: 0,
thread: L
}; /* function will operate over current thread */
}
};
/*
** Variations of 'lua_settable', used by 'db_getinfo' to put results
** from 'lua_getinfo' into result table. Key is always a string;
** value can be a string, an int, or a boolean.
*/
const settabss = function(L, k, v) {
lua.lua_pushstring(L, v);
lua.lua_setfield(L, -2, k);
};
const settabsi = function(L, k, v) {
lua.lua_pushinteger(L, v);
lua.lua_setfield(L, -2, k);
};
const settabsb = function(L, k, v) {
lua.lua_pushboolean(L, v);
lua.lua_setfield(L, -2, k);
};
/*
** In function 'db_getinfo', the call to 'lua_getinfo' may push
** results on the stack; later it creates the result table to put
** these objects. Function 'treatstackoption' puts the result from
** 'lua_getinfo' on top of the result table so that it can call
** 'lua_setfield'.
*/
const treatstackoption = function(L, L1, fname) {
if (L == L1)
lua.lua_rotate(L, -2, 1); /* exchange object and table */
else
lua.lua_xmove(L1, L, 1); /* move object to the "main" stack */
lua.lua_setfield(L, -2, fname); /* put object into table */
};
/*
** Calls 'lua_getinfo' and collects all results in a new table.
** L1 needs stack space for an optional input (function) plus
** two optional outputs (function and line table) from function
** 'lua_getinfo'.
*/
const db_getinfo = function(L) {
let ar = new lua.lua_Debug();
let thread = getthread(L);
let arg = thread.arg;
let L1 = thread.thread;
let options = lauxlib.luaL_optstring(L, arg + 2, lua.to_luastring("flnStu", true));
checkstack(L, L1, 3);
if (lua.lua_isfunction(L, arg + 1)) { /* info about a function? */
options = lua.lua_pushfstring(L, lua.to_luastring(">%s"), options); /* add '>' to 'options' */
lua.lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */
lua.lua_xmove(L, L1, 1);
} else { /* stack level */
if (!lua.lua_getstack(L1, lauxlib.luaL_checkinteger(L, arg + 1), ar)) {
lua.lua_pushnil(L); /* level out of range */
return 1;
}
}
if (!lua.lua_getinfo(L1, options, ar))
lauxlib.luaL_argerror(L, arg + 2, lua.to_luastring("invalid option", true));
lua.lua_newtable(L); /* table to collect results */
if (options.indexOf('S'.charCodeAt(0)) > -1) {
settabss(L, lua.to_luastring("source", true), ar.source);
settabss(L, lua.to_luastring("short_src", true), ar.short_src);
settabsi(L, lua.to_luastring("linedefined", true), ar.linedefined);
settabsi(L, lua.to_luastring("lastlinedefined", true), ar.lastlinedefined);
settabss(L, lua.to_luastring("what", true), ar.what);
}
if (options.indexOf('l'.charCodeAt(0)) > -1)
settabsi(L, lua.to_luastring("currentline", true), ar.currentline);
if (options.indexOf('u'.charCodeAt(0)) > -1) {
settabsi(L, lua.to_luastring("nups", true), ar.nups);
settabsi(L, lua.to_luastring("nparams", true), ar.nparams);
settabsb(L, lua.to_luastring("isvararg", true), ar.isvararg);
}
if (options.indexOf('n'.charCodeAt(0)) > - 1) {
settabss(L, lua.to_luastring("name", true), ar.name);
settabss(L, lua.to_luastring("namewhat", true), ar.namewhat);
}
if (options.indexOf('t'.charCodeAt(0)) > - 1)
settabsb(L, lua.to_luastring("istailcall", true), ar.istailcall);
if (options.indexOf('L'.charCodeAt(0)) > - 1)
treatstackoption(L, L1, lua.to_luastring("activelines", true));
if (options.indexOf('f'.charCodeAt(0)) > - 1)
treatstackoption(L, L1, lua.to_luastring("func", true));
return 1; /* return table */
};
const db_getlocal = function(L) {
let thread = getthread(L);
let L1 = thread.thread;
let arg = thread.arg;
let ar = new lua.lua_Debug();
let nvar = lauxlib.luaL_checkinteger(L, arg + 2); /* local-variable index */
if (lua.lua_isfunction(L, arg + 1)) {
lua.lua_pushvalue(L, arg + 1); /* push function */
lua.lua_pushstring(L, lua.lua_getlocal(L, null, nvar)); /* push local name */
return 1; /* return only name (there is no value) */
} else { /* stack-level argument */
let level = lauxlib.luaL_checkinteger(L, arg + 1);
if (!lua.lua_getstack(L1, level, ar)) /* out of range? */
return lauxlib.luaL_argerror(L, arg+1, lua.to_luastring("level out of range", true));
checkstack(L, L1, 1);
let name = lua.lua_getlocal(L1, ar, nvar);
if (name) {
lua.lua_xmove(L1, L, 1); /* move local value */
lua.lua_pushstring(L, name); /* push name */
lua.lua_rotate(L, -2, 1); /* re-order */
return 2;
}
else {
lua.lua_pushnil(L); /* no name (nor value) */
return 1;
}
}
};
const db_setlocal = function(L) {
let thread = getthread(L);
let L1 = thread.thread;
let arg = thread.arg;
let ar = new lua.lua_Debug();
let level = lauxlib.luaL_checkinteger(L, arg + 1);
let nvar = lauxlib.luaL_checkinteger(L, arg + 2);
if (!lua.lua_getstack(L1, level, ar)) /* out of range? */
return lauxlib.luaL_argerror(L, arg + 1, "level out of range");
lauxlib.luaL_checkany(L, arg + 3);
lua.lua_settop(L, arg + 3);
checkstack(L, L1, 1);
lua.lua_xmove(L, L1, 1);
let name = lua.lua_setlocal(L1, ar, nvar);
if (name === null)
lua.lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */
lua.lua_pushstring(L, name);
return 1;
};
/*
** get (if 'get' is true) or set an upvalue from a closure
*/
const auxupvalue = function(L, get) {
let n = lauxlib.luaL_checkinteger(L, 2); /* upvalue index */
lauxlib.luaL_checktype(L, 1, lua.LUA_TFUNCTION); /* closure */
let name = get ? lua.lua_getupvalue(L, 1, n) : lua.lua_setupvalue(L, 1, n);
if (name === null) return 0;
lua.lua_pushstring(L, name);
lua.lua_insert(L, -(get+1)); /* no-op if get is false */
return get + 1;
};
const db_getupvalue = function(L) {
return auxupvalue(L, 1);
};
const db_setupvalue = function(L) {
lauxlib.luaL_checkany(L, 3);
return auxupvalue(L, 0);
};
/*
** Check whether a given upvalue from a given closure exists and
** returns its index
*/
const checkupval = function(L, argf, argnup) {
let nup = lauxlib.luaL_checkinteger(L, argnup); /* upvalue index */
lauxlib.luaL_checktype(L, argf, lua.LUA_TFUNCTION); /* closure */
lauxlib.luaL_argcheck(L, (lua.lua_getupvalue(L, argf, nup) !== null), argnup, lua.to_luastring("invalid upvalue index", true));
return nup;
};
const db_upvalueid = function(L) {
let n = checkupval(L, 1, 2);
lua.lua_pushlightuserdata(L, lua.lua_upvalueid(L, 1, n));
return 1;
};
const db_upvaluejoin = function(L) {
let n1 = checkupval(L, 1, 2);
let n2 = checkupval(L, 3, 4);
lauxlib.luaL_argcheck(L, !lua.lua_iscfunction(L, 1), 1, lua.to_luastring("Lua function expected", true));
lauxlib.luaL_argcheck(L, !lua.lua_iscfunction(L, 3), 3, lua.to_luastring("Lua function expected", true));
lua.lua_upvaluejoin(L, 1, n1, 3, n2);
return 0;
};
/*
** The hook table at registry[HOOKKEY] maps threads to their current
** hook function. (We only need the unique address of 'HOOKKEY'.)
*/
const HOOKKEY = lua.to_luastring("__hooks__", true);
const hooknames = ["call", "return", "line", "count", "tail call"].map(e => lua.to_luastring(e));
/*
** Call hook function registered at hook table for the current
** thread (if there is one)
*/
const hookf = function(L, ar) {
lua.lua_rawgetp(L, lua.LUA_REGISTRYINDEX, HOOKKEY);
lua.lua_pushthread(L);
if (lua.lua_rawget(L, -2) === lua.LUA_TFUNCTION) { /* is there a hook function? */
lua.lua_pushstring(L, hooknames[ar.event]); /* push event name */
if (ar.currentline >= 0)
lua.lua_pushinteger(L, ar.currentline); /* push current line */
else lua.lua_pushnil(L);
assert(lua.lua_getinfo(L, ["l".charCodeAt(0), "S".charCodeAt(0)], ar));
lua.lua_call(L, 2, 0); /* call hook function */
}
};
/*
** Convert a string mask (for 'sethook') into a bit mask
*/
const makemask = function(smask, count) {
let mask = 0;
if (smask.indexOf("c".charCodeAt(0)) > -1) mask |= lua.LUA_MASKCALL;
if (smask.indexOf("r".charCodeAt(0)) > -1) mask |= lua.LUA_MASKRET;
if (smask.indexOf("l".charCodeAt(0)) > -1) mask |= lua.LUA_MASKLINE;
if (count > 0) mask |= lua.LUA_MASKCOUNT;
return mask;
};
/*
** Convert a bit mask (for 'gethook') into a string mask
*/
const unmakemask = function(mask, smask) {
let i = 0;
if (mask & lua.LUA_MASKCALL) smask[i++] = "c".charCodeAt(0);
if (mask & lua.LUA_MASKRET) smask[i++] = "r".charCodeAt(0);
if (mask & lua.LUA_MASKLINE) smask[i++] = "l".charCodeAt(0);
return smask;
};
const db_sethook = function(L) {
let mask, count, func;
let thread = getthread(L);
let L1 = thread.thread;
let arg = thread.arg;
if (lua.lua_isnoneornil(L, arg+1)) { /* no hook? */
lua.lua_settop(L, arg+1);
func = null; mask = 0; count = 0; /* turn off hooks */
}
else {
const smask = lauxlib.luaL_checkstring(L, arg + 2);
lauxlib.luaL_checktype(L, arg+1, lua.LUA_TFUNCTION);
count = lauxlib.luaL_optinteger(L, arg + 3, 0);
func = hookf; mask = makemask(smask, count);
}
if (lua.lua_rawgetp(L, lua.LUA_REGISTRYINDEX, HOOKKEY) === lua.LUA_TNIL) {
lua.lua_createtable(L, 0, 2); /* create a hook table */
lua.lua_pushvalue(L, -1);
lua.lua_rawsetp(L, lua.LUA_REGISTRYINDEX, HOOKKEY); /* set it in position */
lua.lua_pushstring(L, ["k".charCodeAt(0)]);
lua.lua_setfield(L, -2, lua.to_luastring("__mode", true)); /** hooktable.__mode = "k" */
lua.lua_pushvalue(L, -1);
lua.lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
}
checkstack(L, L1, 1);
lua.lua_pushthread(L1); lua.lua_xmove(L1, L, 1); /* key (thread) */
lua.lua_pushvalue(L, arg + 1); /* value (hook function) */
lua.lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */
lua.lua_sethook(L1, func, mask, count);
return 0;
};
const db_gethook = function(L) {
let thread = getthread(L);
let L1 = thread.thread;
let buff = [];
let mask = lua.lua_gethookmask(L1);
let hook = lua.lua_gethook(L1);
if (hook === null) /* no hook? */
lua.lua_pushnil(L);
else if (hook !== hookf) /* external hook? */
lua.lua_pushliteral(L, "external hook");
else { /* hook table must exist */
lua.lua_rawgetp(L, lua.LUA_REGISTRYINDEX, HOOKKEY);
checkstack(L, L1, 1);
lua.lua_pushthread(L1); lua.lua_xmove(L1, L, 1);
lua.lua_rawget(L, -2); /* 1st result = hooktable[L1] */
lua.lua_remove(L, -2); /* remove hook table */
}
lua.lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */
lua.lua_pushinteger(L, lua.lua_gethookcount(L1)); /* 3rd result = count */
return 3;
};
const db_traceback = function(L) {
let thread = getthread(L);
let L1 = thread.thread;
let arg = thread.arg;
let msg = lua.lua_tostring(L, arg + 1);
if (msg === null && !lua.lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */
lua.lua_pushvalue(L, arg + 1); /* return it untouched */
else {
let level = lauxlib.luaL_optinteger(L, arg + 2, L === L1 ? 1 : 0);
lauxlib.luaL_traceback(L, L1, msg, level);
}
return 1;
};
const dblib = {
"gethook": db_gethook,
"getinfo": db_getinfo,
"getlocal": db_getlocal,
"getmetatable": db_getmetatable,
"getregistry": db_getregistry,
"getupvalue": db_getupvalue,
"getuservalue": db_getuservalue,
"sethook": db_sethook,
"setlocal": db_setlocal,
"setmetatable": db_setmetatable,
"setupvalue": db_setupvalue,
"setuservalue": db_setuservalue,
"traceback": db_traceback,
"upvalueid": db_upvalueid,
"upvaluejoin": db_upvaluejoin
};
// Only with Node
if (false) {
const readlineSync = require('readline-sync');
readlineSync.setDefaultOptions({
prompt: 'lua_debug> '
});
// TODO: if in browser, use a designated input in the DOM ?
const db_debug = function(L) {
for (;;) {
let input = readlineSync.prompt();
if (input === "cont")
return 0;
if (input.length === 0)
continue;
let buffer = lua.to_luastring(input);
if (lauxlib.luaL_loadbuffer(L, buffer, buffer.length, lua.to_luastring("=(debug command)", true))
|| lua.lua_pcall(L, 0, 0, 0)) {
lauxlib.lua_writestringerror(`${lua.lua_tojsstring(L, -1)}\n`);
}
lua.lua_settop(L, 0); /* remove eventual returns */
}
};
dblib.debug = db_debug;
}
const luaopen_debug = function(L) {
lauxlib.luaL_newlib(L, dblib);
return 1;
};
module.exports.luaopen_debug = luaopen_debug;
/***/ }),
/* 51 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const lua = __webpack_require__(3);
const lauxlib = __webpack_require__(9);
const llimit = __webpack_require__(8);
const strftime = __webpack_require__(52);
/* options for ANSI C 89 (only 1-char options) */
const L_STRFTIMEC89 = lua.to_luastring("aAbBcdHIjmMpSUwWxXyYZ%", true);
/* options for ISO C 99 and POSIX */
const L_STRFTIMEC99 = lua.to_luastring("aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%||EcECExEXEyEYOdOeOHOIOmOMOSOuOUOVOwOWOy", true); /* two-char options */
/* options for Windows */
const L_STRFTIMEWIN = lua.to_luastring("aAbBcdHIjmMpSUwWxXyYzZ%||#c#x#d#H#I#j#m#M#S#U#w#W#y#Y", true); /* two-char options */
// const LUA_STRFTIMEOPTIONS = L_STRFTIMEWIN;
const LUA_STRFTIMEOPTIONS = L_STRFTIMEC89;
// const LUA_STRFTIMEOPTIONS = L_STRFTIMEC99;
const setfield = function(L, key, value) {
lua.lua_pushinteger(L, value);
lua.lua_setfield(L, -2, lua.to_luastring(key, true));
};
const setallfields = function(L, time, utc) {
setfield(L, "sec", !utc ? time.getSeconds() : time.getUTCSeconds());
setfield(L, "min", !utc ? time.getMinutes() : time.getUTCMinutes());
setfield(L, "hour", !utc ? time.getHours() : time.getUTCHours());
setfield(L, "day", !utc ? time.getDate() : time.getUTCDate());
setfield(L, "month", !utc ? time.getMonth() : time.getUTCMonth());
setfield(L, "year", !utc ? time.getFullYear() : time.getUTCFullYear());
setfield(L, "wday", !utc ? time.getDay() : time.getUTCDay());
let now = new Date();
setfield(L, "yday", Math.floor((now - (new Date(now.getFullYear(), 0, 0))) / (1000 * 60 * 60 * 24)));
// setboolfield(L, "isdst", time.get);
};
const L_MAXDATEFIELD = (llimit.MAX_INT / 2);
const getfield = function(L, key, d, delta) {
let t = lua.lua_getfield(L, -1, lua.to_luastring(key, true)); /* get field and its type */
let res = lua.lua_tointegerx(L, -1);
if (res === false) { /* field is not an integer? */
if (t !== lua.LUA_TNIL) /* some other value? */
return lauxlib.luaL_error(L, lua.to_luastring("field '%s' is not an integer"), key);
else if (d < 0) /* absent field; no default? */
return lauxlib.luaL_error(L, lua.to_luastring("field '%s' missing in date table"), key);
res = d;
}
else {
if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
return lauxlib.luaL_error(L, lua.to_luastring("field '%s' is out-of-bound"), key);
res -= delta;
}
lua.lua_pop(L, 1);
return res;
};
const checkoption = function(L, conv, buff) {
let option = LUA_STRFTIMEOPTIONS;
let oplen = 1; /* length of options being checked */
for (; option.length > 0 && oplen <= conv.length; option = option.slice(oplen)) {
if (option[0] === '|'.charCodeAt(0)) /* next block? */
oplen++; /* will check options with next length (+1) */
else if (lua.to_jsstring(conv.slice(0, oplen)) === lua.to_jsstring(option.slice(0, oplen))) { /* match? */
buff.push(...conv.slice(0, oplen)); /* copy valid option to buffer */
return conv.slice(oplen); /* return next item */
}
}
lauxlib.luaL_argerror(L, 1, lua.lua_pushliteral(L, `invalid conversion specifier '%${conv}'`, conv));
};
/* maximum size for an individual 'strftime' item */
const SIZETIMEFMT = 250;
const os_date = function(L) {
let s = lauxlib.luaL_optlstring(L, 1, "%c");
let t = lauxlib.luaL_opt(L, l_checktime, 2, new Date().getTime() / 1000) * 1000;
let stm = new Date(t);
let utc = false;
if (s[0] === '!'.charCodeAt(0)) { /* UTC? */
utc = true;
s = s.slice(1); /* skip '!' */
}
if (stm === null) /* invalid date? */
lauxlib.luaL_error(L, lua.to_luastring("time result cannot be represented in this installation", true));
if (lua.to_jsstring(s) === "*t") {
lua.lua_createtable(L, 0, 9); /* 9 = number of fields */
setallfields(L, stm, utc);
} else {
let cc; /* buffer for individual conversion specifiers */
let b = [];
while (s.length > 0) {
cc = ['%'.charCodeAt(0)];
if (s[0] !== '%'.charCodeAt(0)) { /* not a conversion specifier? */
b.push(s[0]);
s = s.slice(1);
} else {
s = s.slice(1); /* skip '%' */
s = checkoption(L, s, cc); /* copy specifier to 'cc' */
b.push(...(lua.to_luastring(strftime(lua.to_jsstring(cc), stm))));
}
}
lua.lua_pushstring(L, b);
}
return 1;
};
const os_time = function(L) {
let t = new Date();
if (!lua.lua_isnoneornil(L, 1)) /* called with arg */{
lauxlib.luaL_checktype(L, 1, lua.LUA_TTABLE); /* make sure table is at the top */
lua.lua_settop(L, 1);
t.setSeconds(getfield(L, "sec", 0, 0));
t.setMinutes(getfield(L, "min", 0, 0));
t.setHours(getfield(L, "hour", 12, 0));
t.setDate(getfield(L, "day", -1, 0));
t.setMonth(getfield(L, "month", -1, 1));
t.setFullYear(getfield(L, "year", -1, 0));
setallfields(L, t);
}
lua.lua_pushinteger(L, Math.floor(t / 1000));
return 1;
};
const l_checktime = function(L, arg) {
let t = lauxlib.luaL_checkinteger(L, arg);
// lauxlib.luaL_argcheck(L, t, arg, lua.to_luastring("time out-of-bounds"));
return t;
};
const os_difftime = function(L) {
let t1 = l_checktime(L, 1);
let t2 = l_checktime(L, 2);
lua.lua_pushnumber(L, new Date(t1) - new Date(t2));
return 1;
};
const syslib = {
"date": os_date,
"difftime": os_difftime,
"time": os_time
};
// Only with Node
if (false) {
const fs = require('fs');
const tmp = require('tmp');
const child_process = require('child_process');
syslib.exit = function(L) {
let status;
if (lua.lua_isboolean(L, 1))
status = (lua.lua_toboolean(L, 1) ? 0 : 1);
else
status = lauxlib.luaL_optinteger(L, 1, 0);
if (lua.lua_toboolean(L, 2))
lua.lua_close(L);
if (L) process.exit(status); /* 'if' to avoid warnings for unreachable 'return' */
return 0;
};
syslib.getenv = function(L) {
lua.lua_pushliteral(L, process.env[lua.to_jsstring(lauxlib.luaL_checkstring(L, 1))]); /* if NULL push nil */
return 1;
};
syslib.clock = function(L) {
lua.lua_pushnumber(L, process.uptime());
return 1;
};
// TODO: on POSIX system, should create the file
const lua_tmpname = function() {
return tmp.tmpNameSync();
};
syslib.remove = function(L) {
let filename = lauxlib.luaL_checkstring(L, 1);
try {
if (fs.lstatSync(lua.to_jsstring(filename)).isDirectory()) {
fs.rmdirSync(lua.to_jsstring(filename));
} else {
fs.unlinkSync(lua.to_jsstring(filename));
}
} catch (e) {
return lauxlib.luaL_fileresult(L, false, filename, e);
}
return lauxlib.luaL_fileresult(L, true);
};
syslib.rename = function(L) {
let fromname = lua.to_jsstring(lauxlib.luaL_checkstring(L, 1));
let toname = lua.to_jsstring(lauxlib.luaL_checkstring(L, 2));
try {
fs.renameSync(fromname, toname);
} catch (e) {
return lauxlib.luaL_fileresult(L, false, false, e);
}
return lauxlib.luaL_fileresult(L, true);
};
syslib.tmpname = function(L) {
let name = lua_tmpname();
if (!name)
return lauxlib.luaL_error(L, lua.to_luastring("unable to generate a unique filename"));
lua.lua_pushstring(L, lua.to_luastring(name));
return 1;
};
syslib.execute = function(L) {
let cmd = lauxlib.luaL_optstring(L, 1, null);
if (cmd !== null) {
try {
child_process.execSync(
lua.to_jsstring(cmd),
{
stdio: [process.stdin, process.stdout, process.stderr]
}
);
} catch (e) {
return lauxlib.luaL_execresult(L, e);
}
return lauxlib.luaL_execresult(L, null);
} else {
try {
child_process.execSync(
lua.to_jsstring(cmd),
{
stdio: [process.stdin, process.stdout, process.stderr]
}
);
lua.lua_pushboolean(L, 1);
} catch (e) {
lua.lua_pushboolean(L, 0);
}
return 1;
}
};
}
const luaopen_os = function(L) {
lauxlib.luaL_newlib(L, syslib);
return 1;
};
module.exports.luaopen_os = luaopen_os;
/***/ }),
/* 52 */
/***/ (function(module, exports) {
//
// strftime
// github.com/samsonjs/strftime
// @_sjs
//
// Copyright 2010 - 2016 Sami Samhuri <sami@samhuri.net>
//
// MIT License
// http://sjs.mit-license.org
//
;(function() {
var Locales = {
de_DE: {
days: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
shortDays: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
shortMonths: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
AM: 'AM',
PM: 'PM',
am: 'am',
pm: 'pm',
formats: {
c: '%a %d %b %Y %X %Z',
D: '%d.%m.%Y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%T',
x: '%D'
}
},
en_CA: {
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
ordinalSuffixes: [
'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
'st'
],
AM: 'AM',
PM: 'PM',
am: 'am',
pm: 'pm',
formats: {
c: '%a %d %b %Y %X %Z',
D: '%d/%m/%y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%r',
x: '%D'
}
},
en_US: {
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
ordinalSuffixes: [
'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
'st'
],
AM: 'AM',
PM: 'PM',
am: 'am',
pm: 'pm',
formats: {
c: '%a %d %b %Y %X %Z',
D: '%m/%d/%y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%r',
x: '%D'
}
},
es_MX: {
days: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado'],
shortDays: ['dom', 'lun', 'mar', 'mié', 'jue', 'vie', 'sáb'],
months: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre',' diciembre'],
shortMonths: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic'],
AM: 'AM',
PM: 'PM',
am: 'am',
pm: 'pm',
formats: {
c: '%a %d %b %Y %X %Z',
D: '%d/%m/%Y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%T',
x: '%D'
}
},
fr_FR: {
days: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
shortDays: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
months: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
shortMonths: ['janv.', 'févr.', 'mars', 'avril', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],
AM: 'AM',
PM: 'PM',
am: 'am',
pm: 'pm',
formats: {
c: '%a %d %b %Y %X %Z',
D: '%d/%m/%Y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%T',
x: '%D'
}
},
it_IT: {
days: ['domenica', 'lunedì', 'martedì', 'mercoledì', 'giovedì', 'venerdì', 'sabato'],
shortDays: ['dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'],
months: ['gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre'],
shortMonths: ['pr', 'mag', 'giu', 'lug', 'ago', 'set', 'ott', 'nov', 'dic'],
AM: 'AM',
PM: 'PM',
am: 'am',
pm: 'pm',
formats: {
c: '%a %d %b %Y %X %Z',
D: '%d/%m/%Y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%T',
x: '%D'
}
},
nl_NL: {
days: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'],
shortDays: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
months: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
shortMonths: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'],
AM: 'AM',
PM: 'PM',
am: 'am',
pm: 'pm',
formats: {
c: '%a %d %b %Y %X %Z',
D: '%d-%m-%y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%T',
x: '%D'
}
},
pt_BR: {
days: ['domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado'],
shortDays: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'],
months: ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'],
shortMonths: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
AM: 'AM',
PM: 'PM',
am: 'am',
pm: 'pm',
formats: {
c: '%a %d %b %Y %X %Z',
D: '%d-%m-%Y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%T',
x: '%D'
}
},
ru_RU: {
days: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'],
shortDays: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
months: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
shortMonths: ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'],
AM: 'AM',
PM: 'PM',
am: 'am',
pm: 'pm',
formats: {
c: '%a %d %b %Y %X',
D: '%d.%m.%y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%T',
x: '%D'
}
},
tr_TR: {
days: ['Pazar', 'Pazartesi', 'Salı','Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi'],
shortDays: ['Paz', 'Pzt', 'Sal', 'Çrş', 'Prş', 'Cum', 'Cts'],
months: ['Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran', 'Temmuz', 'Ağustos', 'Eylül', 'Ekim', 'Kasım', 'Aralık'],
shortMonths: ['Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz', 'Tem', 'Ağu', 'Eyl', 'Eki', 'Kas', 'Ara'],
AM: 'ÖÖ',
PM: 'ÖS',
am: 'ÖÖ',
pm: 'ÖS',
formats: {
c: '%a %d %b %Y %X %Z',
D: '%d-%m-%Y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%T',
x: '%D'
}
},
// By michaeljayt<michaeljayt@gmail.com>
// https://github.com/michaeljayt/strftime/commit/bcb4c12743811d51e568175aa7bff3fd2a77cef3
zh_CN: {
days: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
shortDays: ['日', '一', '二', '三', '四', '五', '六'],
months: ['一月份', '二月份', '三月份', '四月份', '五月份', '六月份', '七月份', '八月份', '九月份', '十月份', '十一月份', '十二月份'],
shortMonths: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
AM: '上午',
PM: '下午',
am: '上午',
pm: '下午',
formats: {
c: '%a %d %b %Y %X %Z',
D: '%d/%m/%y',
F: '%Y-%m-%d',
R: '%H:%M',
r: '%I:%M:%S %p',
T: '%H:%M:%S',
v: '%e-%b-%Y',
X: '%r',
x: '%D'
}
}
};
var DefaultLocale = Locales['en_US'],
defaultStrftime = new Strftime(DefaultLocale, 0, false),
isCommonJS = typeof module !== 'undefined',
namespace;
// CommonJS / Node module
if (isCommonJS) {
namespace = module.exports = defaultStrftime;
}
// Browsers and other environments
else {
// Get the global object. Works in ES3, ES5, and ES5 strict mode.
namespace = (function() { return this || (1,eval)('this'); }());
namespace.strftime = defaultStrftime;
}
// Polyfill Date.now for old browsers.
if (typeof Date.now !== 'function') {
Date.now = function() {
return +new Date();
};
}
function Strftime(locale, customTimezoneOffset, useUtcTimezone) {
var _locale = locale || DefaultLocale,
_customTimezoneOffset = customTimezoneOffset || 0,
_useUtcBasedDate = useUtcTimezone || false,
// we store unix timestamp value here to not create new Date() each iteration (each millisecond)
// Date.now() is 2 times faster than new Date()
// while millisecond precise is enough here
// this could be very helpful when strftime triggered a lot of times one by one
_cachedDateTimestamp = 0,
_cachedDate;
function _strftime(format, date) {
var timestamp;
if (!date) {
var currentTimestamp = Date.now();
if (currentTimestamp > _cachedDateTimestamp) {
_cachedDateTimestamp = currentTimestamp;
_cachedDate = new Date(_cachedDateTimestamp);
timestamp = _cachedDateTimestamp;
if (_useUtcBasedDate) {
// how to avoid duplication of date instantiation for utc here?
// we tied to getTimezoneOffset of the current date
_cachedDate = new Date(_cachedDateTimestamp + getTimestampToUtcOffsetFor(_cachedDate) + _customTimezoneOffset);
}
}
else {
timestamp = _cachedDateTimestamp;
}
date = _cachedDate;
}
else {
timestamp = date.getTime();
if (_useUtcBasedDate) {
var utcOffset = getTimestampToUtcOffsetFor(date);
date = new Date(timestamp + utcOffset + _customTimezoneOffset);
// If we've crossed a DST boundary with this calculation we need to
// adjust the new date accordingly or it will be off by an hour in UTC.
if (getTimestampToUtcOffsetFor(date) !== utcOffset) {
var newUTCOffset = getTimestampToUtcOffsetFor(date);
date = new Date(timestamp + newUTCOffset + _customTimezoneOffset);
}
}
}
return _processFormat(format, date, _locale, timestamp);
}
function _processFormat(format, date, locale, timestamp) {
var resultString = '',
padding = null,
isInScope = false,
length = format.length,
extendedTZ = false;
for (var i = 0; i < length; i++) {
var currentCharCode = format.charCodeAt(i);
if (isInScope === true) {
// '-'
if (currentCharCode === 45) {
padding = '';
continue;
}
// '_'
else if (currentCharCode === 95) {
padding = ' ';
continue;
}
// '0'
else if (currentCharCode === 48) {
padding = '0';
continue;
}
// ':'
else if (currentCharCode === 58) {
if (extendedTZ) {
warn("[WARNING] detected use of unsupported %:: or %::: modifiers to strftime");
}
extendedTZ = true;
continue;
}
switch (currentCharCode) {
// Examples for new Date(0) in GMT
// '%'
// case '%':
case 37:
resultString += '%';
break;
// 'Thursday'
// case 'A':
case 65:
resultString += locale.days[date.getDay()];
break;
// 'January'
// case 'B':
case 66:
resultString += locale.months[date.getMonth()];
break;
// '19'
// case 'C':
case 67:
resultString += padTill2(Math.floor(date.getFullYear() / 100), padding);
break;
// '01/01/70'
// case 'D':
case 68:
resultString += _processFormat(locale.formats.D, date, locale, timestamp);
break;
// '1970-01-01'
// case 'F':
case 70:
resultString += _processFormat(locale.formats.F, date, locale, timestamp);
break;
// '00'
// case 'H':
case 72:
resultString += padTill2(date.getHours(), padding);
break;
// '12'
// case 'I':
case 73:
resultString += padTill2(hours12(date.getHours()), padding);
break;
// '000'
// case 'L':
case 76:
resultString += padTill3(Math.floor(timestamp % 1000));
break;
// '00'
// case 'M':
case 77:
resultString += padTill2(date.getMinutes(), padding);
break;
// 'am'
// case 'P':
case 80:
resultString += date.getHours() < 12 ? locale.am : locale.pm;
break;
// '00:00'
// case 'R':
case 82:
resultString += _processFormat(locale.formats.R, date, locale, timestamp);
break;
// '00'
// case 'S':
case 83:
resultString += padTill2(date.getSeconds(), padding);
break;
// '00:00:00'
// case 'T':
case 84:
resultString += _processFormat(locale.formats.T, date, locale, timestamp);
break;
// '00'
// case 'U':
case 85:
resultString += padTill2(weekNumber(date, 'sunday'), padding);
break;
// '00'
// case 'W':
case 87:
resultString += padTill2(weekNumber(date, 'monday'), padding);
break;
// '16:00:00'
// case 'X':
case 88:
resultString += _processFormat(locale.formats.X, date, locale, timestamp);
break;
// '1970'
// case 'Y':
case 89:
resultString += date.getFullYear();
break;
// 'GMT'
// case 'Z':
case 90:
if (_useUtcBasedDate && _customTimezoneOffset === 0) {
resultString += "GMT";
}
else {
// fixme optimize
var tzString = date.toString().match(/\(([\w\s]+)\)/);
resultString += tzString && tzString[1] || '';
}
break;
// 'Thu'
// case 'a':
case 97:
resultString += locale.shortDays[date.getDay()];
break;
// 'Jan'
// case 'b':
case 98:
resultString += locale.shortMonths[date.getMonth()];
break;
// ''
// case 'c':
case 99:
resultString += _processFormat(locale.formats.c, date, locale, timestamp);
break;
// '01'
// case 'd':
case 100:
resultString += padTill2(date.getDate(), padding);
break;
// ' 1'
// case 'e':
case 101:
resultString += padTill2(date.getDate(), padding == null ? ' ' : padding);
break;
// 'Jan'
// case 'h':
case 104:
resultString += locale.shortMonths[date.getMonth()];
break;
// '000'
// case 'j':
case 106:
var y = new Date(date.getFullYear(), 0, 1);
var day = Math.ceil((date.getTime() - y.getTime()) / (1000 * 60 * 60 * 24));
resultString += padTill3(day);
break;
// ' 0'
// case 'k':
case 107:
resultString += padTill2(date.getHours(), padding == null ? ' ' : padding);
break;
// '12'
// case 'l':
case 108:
resultString += padTill2(hours12(date.getHours()), padding == null ? ' ' : padding);
break;
// '01'
// case 'm':
case 109:
resultString += padTill2(date.getMonth() + 1, padding);
break;
// '\n'
// case 'n':
case 110:
resultString += '\n';
break;
// '1st'
// case 'o':
case 111:
// Try to use an ordinal suffix from the locale, but fall back to using the old
// function for compatibility with old locales that lack them.
var day = date.getDate();
if (locale.ordinalSuffixes) {
resultString += String(day) + (locale.ordinalSuffixes[day - 1] || ordinal(day));
}
else {
resultString += String(day) + ordinal(day);
}
break;
// 'AM'
// case 'p':
case 112:
resultString += date.getHours() < 12 ? locale.AM : locale.PM;
break;
// '12:00:00 AM'
// case 'r':
case 114:
resultString += _processFormat(locale.formats.r, date, locale, timestamp);
break;
// '0'
// case 's':
case 115:
resultString += Math.floor(timestamp / 1000);
break;
// '\t'
// case 't':
case 116:
resultString += '\t';
break;
// '4'
// case 'u':
case 117:
var day = date.getDay();
resultString += day === 0 ? 7 : day;
break; // 1 - 7, Monday is first day of the week
// ' 1-Jan-1970'
// case 'v':
case 118:
resultString += _processFormat(locale.formats.v, date, locale, timestamp);
break;
// '4'
// case 'w':
case 119:
resultString += date.getDay();
break; // 0 - 6, Sunday is first day of the week
// '12/31/69'
// case 'x':
case 120:
resultString += _processFormat(locale.formats.x, date, locale, timestamp);
break;
// '70'
// case 'y':
case 121:
resultString += ('' + date.getFullYear()).slice(2);
break;
// '+0000'
// case 'z':
case 122:
if (_useUtcBasedDate && _customTimezoneOffset === 0) {
resultString += extendedTZ ? "+00:00" : "+0000";
}
else {
var off;
if (_customTimezoneOffset !== 0) {
off = _customTimezoneOffset / (60 * 1000);
}
else {
off = -date.getTimezoneOffset();
}
var sign = off < 0 ? '-' : '+';
var sep = extendedTZ ? ':' : '';
var hours = Math.floor(Math.abs(off / 60));
var mins = Math.abs(off % 60);
resultString += sign + padTill2(hours) + sep + padTill2(mins);
}
break;
default:
if (isInScope) {
resultString += '%';
}
resultString += format[i];
break;
}
padding = null;
isInScope = false;
continue;
}
// '%'
if (currentCharCode === 37) {
isInScope = true;
continue;
}
resultString += format[i];
}
return resultString;
}
var strftime = _strftime;
strftime.localize = function(locale) {
return new Strftime(locale || _locale, _customTimezoneOffset, _useUtcBasedDate);
};
strftime.localizeByIdentifier = function(localeIdentifier) {
var locale = Locales[localeIdentifier];
if (!locale) {
warn('[WARNING] No locale found with identifier "' + localeIdentifier + '".');
return strftime;
}
return strftime.localize(locale);
};
strftime.timezone = function(timezone) {
var customTimezoneOffset = _customTimezoneOffset;
var useUtcBasedDate = _useUtcBasedDate;
var timezoneType = typeof timezone;
if (timezoneType === 'number' || timezoneType === 'string') {
useUtcBasedDate = true;
// ISO 8601 format timezone string, [-+]HHMM
if (timezoneType === 'string') {
var sign = timezone[0] === '-' ? -1 : 1,
hours = parseInt(timezone.slice(1, 3), 10),
minutes = parseInt(timezone.slice(3, 5), 10);
customTimezoneOffset = sign * ((60 * hours) + minutes) * 60 * 1000;
// in minutes: 420
}
else if (timezoneType === 'number') {
customTimezoneOffset = timezone * 60 * 1000;
}
}
return new Strftime(_locale, customTimezoneOffset, useUtcBasedDate);
};
strftime.utc = function() {
return new Strftime(_locale, _customTimezoneOffset, true);
};
return strftime;
}
function padTill2(numberToPad, paddingChar) {
if (paddingChar === '' || numberToPad > 9) {
return numberToPad;
}
if (paddingChar == null) {
paddingChar = '0';
}
return paddingChar + numberToPad;
}
function padTill3(numberToPad) {
if (numberToPad > 99) {
return numberToPad;
}
if (numberToPad > 9) {
return '0' + numberToPad;
}
return '00' + numberToPad;
}
function hours12(hour) {
if (hour === 0) {
return 12;
}
else if (hour > 12) {
return hour - 12;
}
return hour;
}
// firstWeekday: 'sunday' or 'monday', default is 'sunday'
//
// Pilfered & ported from Ruby's strftime implementation.
function weekNumber(date, firstWeekday) {
firstWeekday = firstWeekday || 'sunday';
// This works by shifting the weekday back by one day if we
// are treating Monday as the first day of the week.
var weekday = date.getDay();
if (firstWeekday === 'monday') {
if (weekday === 0) // Sunday
weekday = 6;
else
weekday--;
}
var firstDayOfYearUtc = Date.UTC(date.getFullYear(), 0, 1),
dateUtc = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()),
yday = Math.floor((dateUtc - firstDayOfYearUtc) / 86400000),
weekNum = (yday + 7 - weekday) / 7;
return Math.floor(weekNum);
}
// Get the ordinal suffix for a number: st, nd, rd, or th
function ordinal(number) {
var i = number % 10;
var ii = number % 100;
if ((ii >= 11 && ii <= 13) || i === 0 || i >= 4) {
return 'th';
}
switch (i) {
case 1: return 'st';
case 2: return 'nd';
case 3: return 'rd';
}
}
function getTimestampToUtcOffsetFor(date) {
return (date.getTimezoneOffset() || 0) * 60000;
}
function warn(message) {
if (typeof console !== 'undefined' && typeof console.warn == 'function') {
console.warn(message)
}
}
}());
/***/ }),
/* 53 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const lua = __webpack_require__(3);
const lauxlib = __webpack_require__(9);
const LUA_IGMARK = ["-".charCodeAt(0)];
const CLIBS = lua.to_luastring("__CLIBS__", true);
const LUA_PATH_VAR = "LUA_PATH";
const LUA_CPATH_VAR = "LUA_CPATH";
/*
** LUA_CSUBSEP is the character that replaces dots in submodule names
** when searching for a C loader.
** LUA_LSUBSEP is the character that replaces dots in submodule names
** when searching for a Lua loader.
*/
const LUA_CSUBSEP = lua.LUA_DIRSEP;
const LUA_LSUBSEP = lua.LUA_DIRSEP;
/* prefix for open functions in C libraries */
const LUA_POF = lua.to_luastring("luaopen_");
/* separator for open functions in C libraries */
const LUA_OFSEP = lua.to_luastring("_");
const LIB_FAIL = "open";
const AUXMARK = [1];
/*
** load JS library in file 'path'. If 'seeglb', load with all names in
** the library global.
** Returns the library; in case of error, returns NULL plus an
** error string in the stack.
*/
let lsys_load;
if (true) {
lsys_load = function(L, path) {
let xhr = new XMLHttpRequest();
xhr.open("GET", lua.to_jsstring(path), false);
xhr.send();
if (xhr.status >= 200 && xhr.status <= 299) {
return eval(xhr.response);
} else {
lua.lua_pushstring(L, lua.to_luastring(`${xhr.status}: ${xhr.statusText}`));
return null;
}
};
} else {
lsys_load = function(L, path) {
try {
path = lua.to_jsstring(path);
// Relative path ?
if (path.startsWith('.'))
path = `${process.env.PWD}/${path}`;
return require(path);
} catch (e) {
lua.lua_pushstring(L, lua.to_luastring(e.message));
return null;
}
};
}
/*
** Try to find a function named 'sym' in library 'lib'.
** Returns the function; in case of error, returns NULL plus an
** error string in the stack.
*/
const lsys_sym = function(L, lib, sym) {
let f = lib[lua.to_jsstring(sym)];
if (f && typeof f === 'function')
return f;
else {
lua.lua_pushfstring(L, lua.to_luastring("undefined symbol: %s"), sym);
return null;
}
};
/*
** return registry.LUA_NOENV as a boolean
*/
const noenv = function(L) {
lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring("LUA_NOENV"));
let b = lua.lua_toboolean(L, -1);
lua.lua_pop(L, 1); /* remove value */
return b;
};
let readable;
// Only with Node
if (false) {
const fs = require('fs');
readable = function(filename) {
let fd = false;
try {
fd = fs.openSync(lua.to_jsstring(filename), 'r');
fs.closeSync(fd);
} catch (e) {
return false;
}
return true;
};
} else {
/* TODO: use async/await ? */
readable = function(filename) {
let xhr = new XMLHttpRequest();
/* Following GET request done by searcher_Web will be cached */
xhr.open("GET", lua.to_jsstring(filename), false);
xhr.send();
return xhr.status >= 200 && xhr.status <= 299;
};
}
/* error codes for 'lookforfunc' */
const ERRLIB = 1;
const ERRFUNC = 2;
/*
** Look for a C function named 'sym' in a dynamically loaded library
** 'path'.
** First, check whether the library is already loaded; if not, try
** to load it.
** Then, if 'sym' is '*', return true (as library has been loaded).
** Otherwise, look for symbol 'sym' in the library and push a
** C function with that symbol.
** Return 0 and 'true' or a function in the stack; in case of
** errors, return an error code and an error message in the stack.
*/
const lookforfunc = function(L, path, sym) {
let reg = checkclib(L, path); /* check loaded C libraries */
if (reg === null) { /* must load library? */
reg = lsys_load(L, path, sym[0] === '*'.charCodeAt(0)); /* a global symbols if 'sym'=='*' */
if (reg === null) return ERRLIB; /* unable to load library */
addtoclib(L, path, reg);
}
if (sym[0] === '*'.charCodeAt(0)) { /* loading only library (no function)? */
lua.lua_pushboolean(L, 1); /* return 'true' */
return 0; /* no errors */
}
else {
let f = lsys_sym(L, reg, sym);
if (f === null)
return ERRFUNC; /* unable to find function */
lua.lua_pushcfunction(L, f); /* else create new function */
return 0; /* no errors */
}
};
const ll_loadlib = function(L) {
let path = lauxlib.luaL_checkstring(L, 1);
let init = lauxlib.luaL_checkstring(L, 2);
let stat = lookforfunc(L, path, init);
if (stat === 0) /* no errors? */
return 1; /* return the loaded function */
else { /* error; error message is on stack top */
lua.lua_pushnil(L);
lua.lua_insert(L, -2);
lua.lua_pushliteral(L, (stat === ERRLIB) ? LIB_FAIL : "init");
return 3; /* return nil, error message, and where */
}
};
let env;
if (true) {
env = window;
} else {
env = process.env;
}
/*
** Set a path
*/
const setpath = function(L, fieldname, envname, dft) {
let nver = `${envname}${lua.LUA_VERSUFFIX}`;
lua.lua_pushstring(L, lua.to_luastring(nver));
let path = env[nver]; /* use versioned name */
if (path === undefined) /* no environment variable? */
path = env[envname]; /* try unversioned name */
if (path === undefined || noenv(L)) /* no environment variable? */
lua.lua_pushstring(L, lua.to_luastring(dft, true)); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = lauxlib.luaL_gsub(
L,
lua.to_luastring(path),
lua.to_luastring(lua.LUA_PATH_SEP + lua.LUA_PATH_SEP, true),
lua.to_luastring(lua.LUA_PATH_SEP, true)
.concat(AUXMARK)
.concat(lua.to_luastring(lua.LUA_PATH_SEP, true))
);
lauxlib.luaL_gsub(L, path, AUXMARK, lua.to_luastring(dft));
lua.lua_remove(L, -2); /* remove result from 1st 'gsub' */
}
lua.lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */
lua.lua_pop(L, 1); /* pop versioned variable name */
};
/*
** return registry.CLIBS[path]
*/
const checkclib = function(L, path) {
lua.lua_rawgetp(L, lua.LUA_REGISTRYINDEX, CLIBS);
lua.lua_getfield(L, -1, path);
let plib = lua.lua_touserdata(L, -1); /* plib = CLIBS[path] */
lua.lua_pop(L, 2); /* pop CLIBS table and 'plib' */
return plib;
};
/*
** registry.CLIBS[path] = plib -- for queries
** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries
*/
const addtoclib = function(L, path, plib) {
lua.lua_rawgetp(L, lua.LUA_REGISTRYINDEX, CLIBS);
lua.lua_pushlightuserdata(L, plib);
lua.lua_pushvalue(L, -1);
lua.lua_setfield(L, -3, path); /* CLIBS[path] = plib */
lua.lua_rawseti(L, -2, lauxlib.luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
lua.lua_pop(L, 1); /* pop CLIBS table */
};
const pushnexttemplate = function(L, path) {
while (path[0] === lua.LUA_PATH_SEP.charCodeAt(0)) path = path.slice(1); /* skip separators */
if (path.length === 0) return null; /* no more templates */
let l = path.indexOf(lua.LUA_PATH_SEP.charCodeAt(0)); /* find next separator */
if (l < 0) l = path.length;
lua.lua_pushlstring(L, path, l); /* template */
return path.slice(l);
};
const searchpath = function(L, name, path, sep, dirsep) {
let msg = new lauxlib.luaL_Buffer(); /* to build error message */
lauxlib.luaL_buffinit(L, msg);
if (sep[0] !== 0) /* non-empty separator? */
name = lauxlib.luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
while ((path = pushnexttemplate(L, path)) !== null) {
let filename = lauxlib.luaL_gsub(L, lua.lua_tostring(L, -1), lua.to_luastring(lua.LUA_PATH_MARK, true), name);
lua.lua_remove(L, -2); /* remove path template */
if (readable(filename)) /* does file exist and is readable? */
return filename; /* return that file name */
lua.lua_pushfstring(L, lua.to_luastring("\n\tno file '%s'"), filename);
lua.lua_remove(L, -2); /* remove file name */
lauxlib.luaL_addvalue(msg);
}
lauxlib.luaL_pushresult(msg); /* create error message */
return null; /* not found */
};
const ll_searchpath = function(L) {
let f = searchpath(
L,
lauxlib.luaL_checkstring(L, 1),
lauxlib.luaL_checkstring(L, 2),
lauxlib.luaL_optstring(L, 3, [".".charCodeAt(0)]),
lauxlib.luaL_optstring(L, 4, [lua.LUA_DIRSEP.charCodeAt(0)])
);
if (f !== null) return 1;
else { /* error message is on top of the stack */
lua.lua_pushnil(L);
lua.lua_insert(L, -2);
return 2; /* return nil + error message */
}
};
const findfile = function(L, name, pname, dirsep) {
lua.lua_getfield(L, lua.lua_upvalueindex(1), pname);
let path = lua.lua_tostring(L, -1);
if (path === null)
lauxlib.luaL_error(L, lua.to_luastring("'package.%s' must be a string"), pname);
return searchpath(L, name, path, ['.'.charCodeAt(0)], dirsep);
};
const checkload = function(L, stat, filename) {
if (stat) { /* module loaded successfully? */
lua.lua_pushstring(L, filename); /* will be 2nd argument to module */
return 2; /* return open function and file name */
} else
return lauxlib.luaL_error(L, lua.to_luastring("error loading module '%s' from file '%s':\n\t%s"),
lua.lua_tostring(L, 1), filename, lua.lua_tostring(L, -1));
};
const searcher_Lua = function(L) {
let name = lauxlib.luaL_checkstring(L, 1);
let filename = findfile(L, name, lua.to_luastring("path", true), lua.to_luastring(LUA_LSUBSEP, true));
if (filename === null) return 1; /* module not found in this path */
return checkload(L, lauxlib.luaL_loadfile(L, filename) === lua.LUA_OK, filename);
};
/*
** Try to find a load function for module 'modname' at file 'filename'.
** First, change '.' to '_' in 'modname'; then, if 'modname' has
** the form X-Y (that is, it has an "ignore mark"), build a function
** name "luaopen_X" and look for it. (For compatibility, if that
** fails, it also tries "luaopen_Y".) If there is no ignore mark,
** look for a function named "luaopen_modname".
*/
const loadfunc = function(L, filename, modname) {
let openfunc;
modname = lauxlib.luaL_gsub(L, modname, [".".charCodeAt(0)], LUA_OFSEP);
let mark = modname.indexOf(LUA_IGMARK[0]);
if (mark >= 0) {
openfunc = lua.lua_pushlstring(L, modname, mark);
openfunc = lua.lua_pushfstring(L, lua.to_luastring("%s%s"), LUA_POF, openfunc);
let stat = lookforfunc(L, filename, openfunc);
if (stat !== ERRFUNC) return stat;
modname = mark + 1; /* else go ahead and try old-style name */
}
openfunc = lua.lua_pushfstring(L, lua.to_luastring("%s%s"), LUA_POF, modname);
return lookforfunc(L, filename, openfunc);
};
const searcher_C = function(L) {
let name = lauxlib.luaL_checkstring(L, 1);
let filename = findfile(L, name, lua.to_luastring("cpath", true), lua.to_luastring(LUA_CSUBSEP, true));
if (filename === null) return 1; /* module not found in this path */
return checkload(L, (loadfunc(L, filename, name) === 0), filename);
};
const searcher_Croot = function(L) {
let name = lauxlib.luaL_checkstring(L, 1);
let p = name.indexOf('.'.charCodeAt(0));
let stat;
if (p < 0) return 0; /* is root */
lua.lua_pushlstring(L, name, p);
let filename = findfile(L, lua.lua_tostring(L, -1), lua.to_luastring("cpath", true), lua.to_luastring(LUA_CSUBSEP, true));
if (filename === null) return 1; /* root not found */
if ((stat = loadfunc(L, filename, name)) !== 0) {
if (stat != ERRFUNC)
return checkload(L, 0, filename); /* real error */
else { /* open function not found */
lua.lua_pushstring(L, lua.to_luastring(`\n\tno module '${lua.to_jsstring(name)}' in file '${lua.to_jsstring(filename)}'`));
return 1;
}
}
lua.lua_pushstring(L, filename); /* will be 2nd argument to module */
return 2;
};
const searcher_preload = function(L) {
let name = lauxlib.luaL_checkstring(L, 1);
lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(lauxlib.LUA_PRELOAD_TABLE, true));
if (lua.lua_getfield(L, -1, name) === lua.LUA_TNIL) /* not found? */
lua.lua_pushliteral(L, `\n\tno field package.preload['${lua.to_jsstring(name)}']`);
return 1;
};
const findloader = function(L, name, ctx, k) {
let msg = new lauxlib.luaL_Buffer(); /* to build error message */
lauxlib.luaL_buffinit(L, msg);
/* push 'package.searchers' to index 3 in the stack */
if (lua.lua_getfield(L, lua.lua_upvalueindex(1), lua.to_luastring("searchers", true)) !== lua.LUA_TTABLE)
lauxlib.luaL_error(L, lua.to_luastring("'package.searchers' must be a table"));
let ctx2 = {name: name, i: 1, msg: msg, ctx: ctx, k: k};
return findloader_cont(L, lua.LUA_OK, ctx2);
};
const findloader_cont = function(L, status, ctx) {
/* iterate over available searchers to find a loader */
for (; ; ctx.i++) {
if (status === lua.LUA_OK) {
if (lua.lua_rawgeti(L, 3, ctx.i) === lua.LUA_TNIL) { /* no more searchers? */
lua.lua_pop(L, 1); /* remove nil */
lauxlib.luaL_pushresult(ctx.msg); /* create error message */
lauxlib.luaL_error(L, lua.to_luastring("module '%s' not found:%s"), ctx.name, lua.lua_tostring(L, -1));
}
lua.lua_pushstring(L, ctx.name);
lua.lua_callk(L, 1, 2, ctx, findloader_cont); /* call it */
} else {
status = lua.LUA_OK;
}
if (lua.lua_isfunction(L, -2)) /* did it find a loader? */
break; /* module loader found */
else if (lua.lua_isstring(L, -2)) { /* searcher returned error message? */
lua.lua_pop(L, 1); /* remove extra return */
lauxlib.luaL_addvalue(ctx.msg); /* concatenate error message */
}
else
lua.lua_pop(L, 2); /* remove both returns */
}
return ctx.k(L, lua.LUA_OK, ctx.ctx);
};
const ll_require = function(L) {
let name = lauxlib.luaL_checkstring(L, 1);
lua.lua_settop(L, 1); /* LOADED table will be at index 2 */
lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(lauxlib.LUA_LOADED_TABLE, true));
lua.lua_getfield(L, 2, name); /* LOADED[name] */
if (lua.lua_toboolean(L, -1)) /* is it there? */
return 1; /* package is already loaded */
/* else must load package */
lua.lua_pop(L, 1); /* remove 'getfield' result */
let ctx = name;
return findloader(L, name, ctx, ll_require_cont);
};
const ll_require_cont = function(L, status, ctx) {
let name = ctx;
lua.lua_pushstring(L, name); /* pass name as argument to module loader */
lua.lua_insert(L, -2); /* name is 1st argument (before search data) */
lua.lua_callk(L, 2, 1, ctx, ll_require_cont2);
return ll_require_cont2(L, lua.LUA_OK, ctx); /* run loader to load module */
};
const ll_require_cont2 = function(L, status, ctx) {
let name = ctx;
if (!lua.lua_isnil(L, -1)) /* non-nil return? */
lua.lua_setfield(L, 2, name); /* LOADED[name] = returned value */
if (lua.lua_getfield(L, 2, name) == lua.LUA_TNIL) { /* module set no value? */
lua.lua_pushboolean(L, 1); /* use true as result */
lua.lua_pushvalue(L, -1); /* extra copy to be returned */
lua.lua_setfield(L, 2, name); /* LOADED[name] = true */
}
return 1;
};
const pk_funcs = {
"loadlib": ll_loadlib,
"searchpath": ll_searchpath
};
const ll_funcs = {
"require": ll_require
};
const createsearcherstable = function(L) {
let searchers = [searcher_preload, searcher_Lua, searcher_C, searcher_Croot, null];
/* create 'searchers' table */
lua.lua_createtable(L);
/* fill it with predefined searchers */
for (let i = 0; searchers[i]; i++) {
lua.lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */
lua.lua_pushcclosure(L, searchers[i], 1);
lua.lua_rawseti(L, -2, i+1);
}
lua.lua_setfield(L, -2, lua.to_luastring("searchers", true)); /* put it in field 'searchers' */
};
/*
** create table CLIBS to keep track of loaded C libraries,
** setting a finalizer to close all libraries when closing state.
*/
const createclibstable = function(L) {
lua.lua_newtable(L); /* create CLIBS table */
lua.lua_createtable(L, 0, 1); /* create metatable for CLIBS */
lua.lua_setmetatable(L, -2);
lua.lua_rawsetp(L, lua.LUA_REGISTRYINDEX, CLIBS); /* set CLIBS table in registry */
};
const luaopen_package = function(L) {
createclibstable(L);
lauxlib.luaL_newlib(L, pk_funcs); /* create 'package' table */
createsearcherstable(L);
/* set paths */
setpath(L, lua.to_luastring("path", true), LUA_PATH_VAR, lua.LUA_PATH_DEFAULT);
setpath(L, lua.to_luastring("cpath", true), LUA_CPATH_VAR, lua.LUA_CPATH_DEFAULT);
/* store config information */
lua.lua_pushliteral(L, lua.LUA_DIRSEP + "\n" + lua.LUA_PATH_SEP + "\n" + lua.LUA_PATH_MARK + "\n" +
lua.LUA_EXEC_DIR + "\n" + LUA_IGMARK + "\n");
lua.lua_setfield(L, -2, lua.to_luastring("config", true));
/* set field 'loaded' */
lauxlib.luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(lauxlib.LUA_LOADED_TABLE, true));
lua.lua_setfield(L, -2, lua.to_luastring("loaded", true));
/* set field 'preload' */
lauxlib.luaL_getsubtable(L, lua.LUA_REGISTRYINDEX, lua.to_luastring(lauxlib.LUA_PRELOAD_TABLE, true));
lua.lua_setfield(L, -2, lua.to_luastring("preload", true));
lua.lua_pushglobaltable(L);
lua.lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
lauxlib.luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
lua.lua_pop(L, 1); /* pop global table */
return 1; /* return 'package' table */
};
module.exports.luaopen_package = luaopen_package;
/***/ }),
/* 54 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const lisdigit = function(c) {
return /^\d$/.test(String.fromCharCode(c));
};
const lisxdigit = function(c) {
return /^[0-9a-fA-F]$/.test(String.fromCharCode(c));
};
const lisprint = function(c) {
return /^[\x20-\x7E]$/.test(String.fromCharCode(c));
};
const lisspace = function(c) {
return /^\s$/.test(String.fromCharCode(c));
};
const lislalpha = function(c) {
return /^[_a-zA-Z]$/.test(String.fromCharCode(c));
};
const lislalnum = function(c) {
return /^[_a-zA-Z0-9]$/.test(String.fromCharCode(c));
};
module.exports.lisdigit = lisdigit;
module.exports.lislalnum = lislalnum;
module.exports.lislalpha = lislalpha;
module.exports.lisprint = lisprint;
module.exports.lisspace = lisspace;
module.exports.lisxdigit = lisxdigit;
/***/ }),
/* 55 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const lcode = __webpack_require__(85);
const ldo = __webpack_require__(13);
const lfunc = __webpack_require__(24);
const llex = __webpack_require__(56);
const llimit = __webpack_require__(10);
const lobject = __webpack_require__(7);
const lopcodes = __webpack_require__(33);
const lstring = __webpack_require__(17);
const ltable = __webpack_require__(16);
const BinOpr = lcode.BinOpr;
const OpCodesI = lopcodes.OpCodesI;
const Proto = lfunc.Proto;
const R = llex.RESERVED;
const UnOpr = lcode.UnOpr;
const char = defs.char;
const MAXVARS = 200;
const hasmultret = function(k) {
return k === expkind.VCALL || k === expkind.VVARARG;
};
const eqstr = function(a, b) {
/* TODO: use plain equality as strings are cached */
return lstring.luaS_eqlngstr(a, b);
};
class BlockCnt {
constructor() {
this.previous = null; /* chain */
this.firstlabel = NaN; /* index of first label in this block */
this.firstgoto = NaN; /* index of first pending goto in this block */
this.nactvar = NaN; /* # active locals outside the block */
this.upval = NaN; /* true if some variable in the block is an upvalue */
this.isloop = NaN; /* true if 'block' is a loop */
}
}
const expkind = {
VVOID: 0, /* when 'expdesc' describes the last expression a list,
this kind means an empty list (so, no expression) */
VNIL: 1, /* constant nil */
VTRUE: 2, /* constant true */
VFALSE: 3, /* constant false */
VK: 4, /* constant in 'k'; info = index of constant in 'k' */
VKFLT: 5, /* floating constant; nval = numerical float value */
VKINT: 6, /* integer constant; nval = numerical integer value */
VNONRELOC: 7, /* expression has its value in a fixed register;
info = result register */
VLOCAL: 8, /* local variable; info = local register */
VUPVAL: 9, /* upvalue variable; info = index of upvalue in 'upvalues' */
VINDEXED: 10, /* indexed variable;
ind.vt = whether 't' is register or upvalue;
ind.t = table register or upvalue;
ind.idx = key's R/K index */
VJMP: 11, /* expression is a test/comparison;
info = pc of corresponding jump instruction */
VRELOCABLE: 12, /* expression can put result in any register;
info = instruction pc */
VCALL: 13, /* expression is a function call; info = instruction pc */
VVARARG: 14 /* vararg expression; info = instruction pc */
};
const vkisvar = function(k) {
return expkind.VLOCAL <= k && k <= expkind.VINDEXED;
};
const vkisinreg = function(k) {
return k === expkind.VNONRELOC || k === expkind.VLOCAL;
};
class expdesc {
constructor() {
this.k = NaN;
this.u = {
ival: NaN, /* for VKINT */
nval: NaN, /* for VKFLT */
info: NaN, /* for generic use */
ind: { /* for indexed variables (VINDEXED) */
idx: NaN, /* index (R/K) */
t: NaN, /* table (register or upvalue) */
vt: NaN /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
}
};
this.t = NaN; /* patch list of 'exit when true' */
this.f = NaN; /* patch list of 'exit when false' */
}
to(e) { // Copy e content to this, cf. luaK_posfix
this.k = e.k;
this.u = e.u;
this.t = e.t;
this.f = e.f;
}
}
class FuncState {
constructor() {
this.f = null; /* current function header */
this.prev = null; /* enclosing function */
this.ls = null; /* lexical state */
this.bl = null; /* chain of current blocks */
this.pc = NaN; /* next position to code (equivalent to 'ncode') */
this.lasttarget = NaN; /* 'label' of last 'jump label' */
this.jpc = NaN; /* list of pending jumps to 'pc' */
this.nk = NaN; /* number of elements in 'k' */
this.np = NaN; /* number of elements in 'p' */
this.firstlocal = NaN; /* index of first local var (in Dyndata array) */
this.nlocvars = NaN; /* number of elements in 'f->locvars' */
this.nactvar = NaN; /* number of active local variables */
this.nups = NaN; /* number of upvalues */
this.freereg = NaN; /* first free register */
}
}
/* description of active local variable */
class Vardesc {
constructor() {
this.idx = NaN; /* variable index in stack */
}
}
/* description of pending goto statements and label statements */
class Labeldesc {
constructor() {
this.name = null; /* label identifier */
this.pc = NaN; /* position in code */
this.line = NaN; /* line where it appeared */
this.nactvar = NaN; /* local level where it appears in current block */
}
}
/* list of labels or gotos */
class Labellist {
constructor() {
this.arr = []; /* array */
this.n = NaN; /* number of entries in use */
this.size = NaN; /* array size */
}
}
/* dynamic structures used by the parser */
class Dyndata {
constructor() {
this.actvar = { /* list of active local variables */
arr: [],
n: NaN,
size: NaN
};
this.gt = new Labellist();
this.label = new Labellist();
}
}
const semerror = function(ls, msg) {
ls.t.token = 0; /* remove "near <token>" from final message */
llex.luaX_syntaxerror(ls, msg);
};
const error_expected = function(ls, token) {
llex.luaX_syntaxerror(ls, lobject.luaO_pushfstring(ls.L, defs.to_luastring("%s expected", true), llex.luaX_token2str(ls, token)));
};
const errorlimit = function(fs, limit, what) {
let L = fs.ls.L;
let line = fs.f.linedefined;
let where = (line === 0)
? defs.to_luastring("main function", true)
: lobject.luaO_pushfstring(L, defs.to_luastring("function at line %d", true), line);
let msg = lobject.luaO_pushfstring(L, defs.to_luastring("too many %s (limit is %d) in %s", true),
what, limit, where);
llex.luaX_syntaxerror(fs.ls, msg);
};
const checklimit = function(fs, v, l, what) {
if (v > l) errorlimit(fs, l, what);
};
const testnext = function(ls, c) {
if (ls.t.token === c) {
llex.luaX_next(ls);
return true;
}
return false;
};
const check = function(ls, c) {
if (ls.t.token !== c)
error_expected(ls, c);
};
const checknext = function(ls, c) {
check(ls, c);
llex.luaX_next(ls);
};
const check_condition = function(ls, c, msg) {
if (!c)
llex.luaX_syntaxerror(ls, msg);
};
const check_match = function(ls, what, who, where) {
if (!testnext(ls, what)) {
if (where === ls.linenumber)
error_expected(ls, what);
else
llex.luaX_syntaxerror(ls, lobject.luaO_pushfstring(ls.L,
defs.to_luastring("%s expected (to close %s at line %d)"),
llex.luaX_token2str(ls, what), llex.luaX_token2str(ls, who), where));
}
};
const str_checkname = function(ls) {
check(ls, R.TK_NAME);
let ts = ls.t.seminfo.ts;
llex.luaX_next(ls);
return ts;
};
const init_exp = function(e, k, i) {
e.f = e.t = lcode.NO_JUMP;
e.k = k;
e.u.info = i;
};
const codestring = function(ls, e, s) {
init_exp(e, expkind.VK, lcode.luaK_stringK(ls.fs, s));
};
const checkname = function(ls, e) {
codestring(ls, e, str_checkname(ls));
};
const registerlocalvar = function(ls, varname) {
let fs = ls.fs;
let f = fs.f;
f.locvars[fs.nlocvars] = new lobject.LocVar();
f.locvars[fs.nlocvars].varname = varname;
return fs.nlocvars++;
};
const new_localvar = function(ls, name) {
let fs = ls.fs;
let dyd = ls.dyd;
let reg = registerlocalvar(ls, name);
checklimit(fs, dyd.actvar.n + 1 - fs.firstlocal, MAXVARS, defs.to_luastring("local variables", true));
dyd.actvar.arr[dyd.actvar.n] = new Vardesc();
dyd.actvar.arr[dyd.actvar.n].idx = reg;
dyd.actvar.n++;
};
const new_localvarliteral = function(ls, name) {
new_localvar(ls, llex.luaX_newstring(ls, defs.to_luastring(name, true)));
};
const getlocvar = function(fs, i) {
let idx = fs.ls.dyd.actvar.arr[fs.firstlocal + i].idx;
assert(idx < fs.nlocvars);
return fs.f.locvars[idx];
};
const adjustlocalvars = function(ls, nvars) {
let fs = ls.fs;
fs.nactvar = fs.nactvar + nvars;
for (; nvars; nvars--)
getlocvar(fs, fs.nactvar - nvars).startpc = fs.pc;
};
const removevars = function(fs, tolevel) {
fs.ls.dyd.actvar.n -= fs.nactvar - tolevel;
while (fs.nactvar > tolevel)
getlocvar(fs, --fs.nactvar).endpc = fs.pc;
};
const searchupvalue = function(fs, name) {
let up = fs.f.upvalues;
for (let i = 0; i < fs.nups; i++) {
if (eqstr(up[i].name, name))
return i;
}
return -1; /* not found */
};
const newupvalue = function(fs, name, v) {
let f = fs.f;
checklimit(fs, fs.nups + 1, lfunc.MAXUPVAL, defs.to_luastring("upvalues", true));
f.upvalues[fs.nups] = {
instack: v.k === expkind.VLOCAL,
idx: v.u.info,
name: name
};
return fs.nups++;
};
const searchvar = function(fs, n) {
for (let i = fs.nactvar - 1; i >= 0; i--) {
if (eqstr(n, getlocvar(fs, i).varname))
return i;
}
return -1;
};
/*
** Mark block where variable at given level was defined
** (to emit close instructions later).
*/
const markupval = function(fs, level) {
let bl = fs.bl;
while (bl.nactvar > level)
bl = bl.previous;
bl.upval = 1;
};
/*
** Find variable with given name 'n'. If it is an upvalue, add this
** upvalue into all intermediate functions.
*/
const singlevaraux = function(fs, n, vr, base) {
if (fs === null) /* no more levels? */
init_exp(vr, expkind.VVOID, 0); /* default is global */
else {
let v = searchvar(fs, n); /* look up locals at current level */
if (v >= 0) { /* found? */
init_exp(vr, expkind.VLOCAL, v); /* variable is local */
if (!base)
markupval(fs, v); /* local will be used as an upval */
} else { /* not found as local at current level; try upvalues */
let idx = searchupvalue(fs, n); /* try existing upvalues */
if (idx < 0) { /* not found? */
singlevaraux(fs.prev, n, vr, 0); /* try upper levels */
if (vr.k === expkind.VVOID) /* not found? */
return; /* it is a global */
/* else was LOCAL or UPVAL */
idx = newupvalue(fs, n, vr); /* will be a new upvalue */
}
init_exp(vr, expkind.VUPVAL, idx); /* new or old upvalue */
}
}
};
const singlevar = function(ls, vr) {
let varname = str_checkname(ls);
let fs = ls.fs;
singlevaraux(fs, varname, vr, 1);
if (vr.k === expkind.VVOID) { /* global name? */
let key = new expdesc();
singlevaraux(fs, ls.envn, vr, 1); /* get environment variable */
assert(vr.k !== expkind.VVOID); /* this one must exist */
codestring(ls, key, varname); /* key is variable name */
lcode.luaK_indexed(fs, vr, key); /* env[varname] */
}
};
const adjust_assign = function(ls, nvars, nexps, e) {
let fs = ls.fs;
let extra = nvars - nexps;
if (hasmultret(e.k)) {
extra++; /* includes call itself */
if (extra < 0) extra = 0;
lcode.luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
if (extra > 1) lcode.luaK_reserveregs(fs, extra - 1);
} else {
if (e.k !== expkind.VVOID) lcode.luaK_exp2nextreg(fs, e); /* close last expression */
if (extra > 0) {
let reg = fs.freereg;
lcode.luaK_reserveregs(fs, extra);
lcode.luaK_nil(fs, reg, extra);
}
}
if (nexps > nvars)
ls.fs.freereg -= nexps - nvars; /* remove extra values */
};
const enterlevel = function(ls) {
let L = ls.L;
++L.nCcalls;
checklimit(ls.fs, L.nCcalls, llimit.LUAI_MAXCCALLS, defs.to_luastring("JS levels", true));
};
const leavelevel = function(ls) {
return ls.L.nCcalls--;
};
const closegoto = function(ls, g, label) {
let fs = ls.fs;
let gl = ls.dyd.gt;
let gt = gl.arr[g];
assert(eqstr(gt.name, label.name));
if (gt.nactvar < label.nactvar) {
let vname = getlocvar(fs, gt.nactvar).varname;
let msg = lobject.luaO_pushfstring(ls.L,
defs.to_luastring("<goto %s> at line %d jumps into the scope of local '%s'"),
gt.name.getstr(), gt.line, vname.getstr());
semerror(ls, msg);
}
lcode.luaK_patchlist(fs, gt.pc, label.pc);
/* remove goto from pending list */
for (let i = g; i < gl.n - 1; i++)
gl.arr[i] = gl.arr[i + 1];
gl.n--;
};
/*
** try to close a goto with existing labels; this solves backward jumps
*/
const findlabel = function(ls, g) {
let bl = ls.fs.bl;
let dyd = ls.dyd;
let gt = dyd.gt.arr[g];
/* check labels in current block for a match */
for (let i = bl.firstlabel; i < dyd.label.n; i++) {
let lb = dyd.label.arr[i];
if (eqstr(lb.name, gt.name)) { /* correct label? */
if (gt.nactvar > lb.nactvar && (bl.upval || dyd.label.n > bl.firstlabel))
lcode.luaK_patchclose(ls.fs, gt.pc, lb.nactvar);
closegoto(ls, g, lb); /* close it */
return true;
}
}
return false; /* label not found; cannot close goto */
};
const newlabelentry = function(ls, l, name, line, pc) {
let n = l.n;
l.arr[n] = new Labeldesc();
l.arr[n].name = name;
l.arr[n].line = line;
l.arr[n].nactvar = ls.fs.nactvar;
l.arr[n].pc = pc;
l.n = n + 1;
return n;
};
/*
** check whether new label 'lb' matches any pending gotos in current
** block; solves forward jumps
*/
const findgotos = function(ls, lb) {
let gl = ls.dyd.gt;
let i = ls.fs.bl.firstgoto;
while (i < gl.n) {
if (eqstr(gl.arr[i].name, lb.name))
closegoto(ls, i, lb);
else
i++;
}
};
/*
** export pending gotos to outer level, to check them against
** outer labels; if the block being exited has upvalues, and
** the goto exits the scope of any variable (which can be the
** upvalue), close those variables being exited.
*/
const movegotosout = function(fs, bl) {
let i = bl.firstgoto;
let gl = fs.ls.dyd.gt;
/* correct pending gotos to current block and try to close it
with visible labels */
while (i < gl.n) {
let gt = gl.arr[i];
if (gt.nactvar > bl.nactvar) {
if (bl.upval)
lcode.luaK_patchclose(fs, gt.pc, bl.nactvar);
gt.nactvar = bl.nactvar;
}
if (!findlabel(fs.ls, i))
i++; /* move to next one */
}
};
const enterblock = function(fs, bl, isloop) {
bl.isloop = isloop;
bl.nactvar = fs.nactvar;
bl.firstlabel = fs.ls.dyd.label.n;
bl.firstgoto = fs.ls.dyd.gt.n;
bl.upval = 0;
bl.previous = fs.bl;
fs.bl = bl;
assert(fs.freereg === fs.nactvar);
};
/*
** create a label named 'break' to resolve break statements
*/
const breaklabel = function(ls) {
let n = lstring.luaS_newliteral(ls.L, "break");
let l = newlabelentry(ls, ls.dyd.label, n, 0, ls.fs.pc);
findgotos(ls, ls.dyd.label.arr[l]);
};
/*
** generates an error for an undefined 'goto'; choose appropriate
** message when label name is a reserved word (which can only be 'break')
*/
const undefgoto = function(ls, gt) {
let msg = llex.isreserved(gt.name)
? "<%s> at line %d not inside a loop"
: "no visible label '%s' for <goto> at line %d";
msg = lobject.luaO_pushfstring(ls.L, defs.to_luastring(msg), gt.name.getstr(), gt.line);
semerror(ls, msg);
};
/*
** adds a new prototype into list of prototypes
*/
const addprototype = function(ls) {
let L = ls.L;
let clp = new Proto(L);
let fs = ls.fs;
let f = fs.f; /* prototype of current function */
f.p[fs.np++] = clp;
return clp;
};
/*
** codes instruction to create new closure in parent function.
*/
const codeclosure = function(ls, v) {
let fs = ls.fs.prev;
init_exp(v, expkind.VRELOCABLE, lcode.luaK_codeABx(fs, OpCodesI.OP_CLOSURE, 0, fs.np -1));
lcode.luaK_exp2nextreg(fs, v); /* fix it at the last register */
};
const open_func = function(ls, fs, bl) {
fs.prev = ls.fs; /* linked list of funcstates */
fs.ls = ls;
ls.fs = fs;
fs.pc = 0;
fs.lasttarget = 0;
fs.jpc = lcode.NO_JUMP;
fs.freereg = 0;
fs.nk = 0;
fs.np = 0;
fs.nups = 0;
fs.nlocvars = 0;
fs.nactvar = 0;
fs.firstlocal = ls.dyd.actvar.n;
fs.bl = null;
let f = new Proto(ls.L);
f = fs.f;
f.source = ls.source;
f.maxstacksize = 2; /* registers 0/1 are always valid */
enterblock(fs, bl, false);
};
const leaveblock = function(fs) {
let bl = fs.bl;
let ls = fs.ls;
if (bl.previous && bl.upval) {
/* create a 'jump to here' to close upvalues */
let j = lcode.luaK_jump(fs);
lcode.luaK_patchclose(fs, j , bl.nactvar);
lcode.luaK_patchtohere(fs, j);
}
if (bl.isloop)
breaklabel(ls); /* close pending breaks */
fs.bl = bl.previous;
removevars(fs, bl.nactvar);
assert(bl.nactvar === fs.nactvar);
fs.freereg = fs.nactvar; /* free registers */
ls.dyd.label.n = bl.firstlabel; /* remove local labels */
if (bl.previous) /* inner block? */
movegotosout(fs, bl); /* update pending gotos to outer block */
else if (bl.firstgoto < ls.dyd.gt.n) /* pending gotos in outer block? */
undefgoto(ls, ls.dyd.gt.arr[bl.firstgoto]); /* error */
};
const close_func = function(ls) {
let fs = ls.fs;
lcode.luaK_ret(fs, 0, 0); /* final return */
leaveblock(fs);
assert(fs.bl === null);
ls.fs = fs.prev;
};
/*============================================================*/
/* GRAMMAR RULES */
/*============================================================*/
const block_follow = function(ls, withuntil) {
switch (ls.t.token) {
case R.TK_ELSE: case R.TK_ELSEIF:
case R.TK_END: case R.TK_EOS:
return true;
case R.TK_UNTIL: return withuntil;
default: return false;
}
};
const statlist = function(ls) {
/* statlist -> { stat [';'] } */
while (!block_follow(ls, 1)) {
if (ls.t.token === R.TK_RETURN) {
statement(ls);
return; /* 'return' must be last statement */
}
statement(ls);
}
};
const fieldsel = function(ls, v) {
/* fieldsel -> ['.' | ':'] NAME */
let fs = ls.fs;
let key = new expdesc();
lcode.luaK_exp2anyregup(fs, v);
llex.luaX_next(ls); /* skip the dot or colon */
checkname(ls, key);
lcode.luaK_indexed(fs, v, key);
};
const yindex = function(ls, v) {
/* index -> '[' expr ']' */
llex.luaX_next(ls); /* skip the '[' */
expr(ls, v);
lcode.luaK_exp2val(ls.fs, v);
checknext(ls, char[']']);
};
/*
** {======================================================================
** Rules for Constructors
** =======================================================================
*/
class ConsControl {
constructor() {
this.v = new expdesc(); /* last list item read */
this.t = new expdesc(); /* table descriptor */
this.nh = NaN; /* total number of 'record' elements */
this.na = NaN; /* total number of array elements */
this.tostore = NaN; /* number of array elements pending to be stored */
}
}
const recfield = function(ls, cc) {
/* recfield -> (NAME | '['exp1']') = exp1 */
let fs = ls.fs;
let reg = ls.fs.freereg;
let key = new expdesc();
let val = new expdesc();
if (ls.t.token === R.TK_NAME) {
checklimit(fs, cc.nh, llimit.MAX_INT, defs.to_luastring("items in a constructor", true));
checkname(ls, key);
} else /* ls->t.token === '[' */
yindex(ls, key);
cc.nh++;
checknext(ls, char['=']);
let rkkey = lcode.luaK_exp2RK(fs, key);
expr(ls, val);
lcode.luaK_codeABC(fs, OpCodesI.OP_SETTABLE, cc.t.u.info, rkkey, lcode.luaK_exp2RK(fs, val));
fs.freereg = reg; /* free registers */
};
const closelistfield = function(fs, cc) {
if (cc.v.k === expkind.VVOID) return; /* there is no list item */
lcode.luaK_exp2nextreg(fs, cc.v);
cc.v.k = expkind.VVOID;
if (cc.tostore === lopcodes.LFIELDS_PER_FLUSH) {
lcode.luaK_setlist(fs, cc.t.u.info, cc.na, cc.tostore); /* flush */
cc.tostore = 0; /* no more items pending */
}
};
const lastlistfield = function(fs, cc) {
if (cc.tostore === 0) return;
if (hasmultret(cc.v.k)) {
lcode.luaK_setmultret(fs, cc.v);
lcode.luaK_setlist(fs, cc.t.u.info, cc.na, defs.LUA_MULTRET);
cc.na--; /* do not count last expression (unknown number of elements) */
} else {
if (cc.v.k !== expkind.VVOID)
lcode.luaK_exp2nextreg(fs, cc.v);
lcode.luaK_setlist(fs, cc.t.u.info, cc.na, cc.tostore);
}
};
const listfield = function(ls, cc) {
/* listfield -> exp */
expr(ls, cc.v);
checklimit(ls.fs, cc.na, llimit.MAX_INT, defs.to_luastring("items in a constructor", true));
cc.na++;
cc.tostore++;
};
const field = function(ls, cc) {
/* field -> listfield | recfield */
switch (ls.t.token) {
case R.TK_NAME: { /* may be 'listfield' or 'recfield' */
if (llex.luaX_lookahead(ls) !== char['=']) /* expression? */
listfield(ls, cc);
else
recfield(ls, cc);
break;
}
case char['[']: {
recfield(ls, cc);
break;
}
default: {
listfield(ls, cc);
break;
}
}
};
const constructor = function(ls, t) {
/* constructor -> '{' [ field { sep field } [sep] ] '}'
sep -> ',' | ';' */
let fs = ls.fs;
let line = ls.linenumber;
let pc = lcode.luaK_codeABC(fs, OpCodesI.OP_NEWTABLE, 0, 0, 0);
let cc = new ConsControl();
cc.na = cc.nh = cc.tostore = 0;
cc.t = t;
init_exp(t, expkind.VRELOCABLE, pc);
init_exp(cc.v, expkind.VVOID, 0); /* no value (yet) */
lcode.luaK_exp2nextreg(ls.fs, t); /* fix it at stack top */
checknext(ls, char['{']);
do {
assert(cc.v.k === expkind.VVOID || cc.tostore > 0);
if (ls.t.token === char['}']) break;
closelistfield(fs, cc);
field(ls, cc);
} while (testnext(ls, char[',']) || testnext(ls, char[';']));
check_match(ls, char['}'], char['{'], line);
lastlistfield(fs, cc);
lopcodes.SETARG_B(fs.f.code[pc], lobject.luaO_int2fb(cc.na)); /* set initial array size */
lopcodes.SETARG_C(fs.f.code[pc], lobject.luaO_int2fb(cc.nh)); /* set initial table size */
};
/* }====================================================================== */
const parlist = function(ls) {
/* parlist -> [ param { ',' param } ] */
let fs = ls.fs;
let f = fs.f;
let nparams = 0;
f.is_vararg = false;
if (ls.t.token !== char[')']) { /* is 'parlist' not empty? */
do {
switch (ls.t.token) {
case R.TK_NAME: { /* param -> NAME */
new_localvar(ls, str_checkname(ls));
nparams++;
break;
}
case R.TK_DOTS: { /* param -> '...' */
llex.luaX_next(ls);
f.is_vararg = true; /* declared vararg */
break;
}
default: llex.luaX_syntaxerror(ls, defs.to_luastring("<name> or '...' expected", true));
}
} while(!f.is_vararg && testnext(ls, char[',']));
}
adjustlocalvars(ls, nparams);
f.numparams = fs.nactvar;
lcode.luaK_reserveregs(fs, fs.nactvar); /* reserve register for parameters */
};
const body = function(ls, e, ismethod, line) {
/* body -> '(' parlist ')' block END */
let new_fs = new FuncState();
let bl = new BlockCnt();
new_fs.f = addprototype(ls);
new_fs.f.linedefined = line;
open_func(ls, new_fs, bl);
checknext(ls, char['(']);
if (ismethod) {
new_localvarliteral(ls, "self"); /* create 'self' parameter */
adjustlocalvars(ls, 1);
}
parlist(ls);
checknext(ls, char[')']);
statlist(ls);
new_fs.f.lastlinedefined = ls.linenumber;
check_match(ls, R.TK_END, R.TK_FUNCTION, line);
codeclosure(ls, e);
close_func(ls);
};
const explist = function(ls, v) {
/* explist -> expr { ',' expr } */
let n = 1; /* at least one expression */
expr(ls, v);
while (testnext(ls, char[','])) {
lcode.luaK_exp2nextreg(ls.fs, v);
expr(ls, v);
n++;
}
return n;
};
const funcargs = function(ls, f, line) {
let fs = ls.fs;
let args = new expdesc();
switch (ls.t.token) {
case char['(']: { /* funcargs -> '(' [ explist ] ')' */
llex.luaX_next(ls);
if (ls.t.token === char[')']) /* arg list is empty? */
args.k = expkind.VVOID;
else {
explist(ls, args);
lcode.luaK_setmultret(fs, args);
}
check_match(ls, char[')'], char['('], line);
break;
}
case char['{']: { /* funcargs -> constructor */
constructor(ls, args);
break;
}
case R.TK_STRING: { /* funcargs -> STRING */
codestring(ls, args, ls.t.seminfo.ts);
llex.luaX_next(ls); /* must use 'seminfo' before 'next' */
break;
}
default: {
llex.luaX_syntaxerror(ls, defs.to_luastring("function arguments expected", true));
}
}
assert(f.k === expkind.VNONRELOC);
let nparams;
let base = f.u.info; /* base register for call */
if (hasmultret(args.k))
nparams = defs.LUA_MULTRET; /* open call */
else {
if (args.k !== expkind.VVOID)
lcode.luaK_exp2nextreg(fs, args); /* close last argument */
nparams = fs.freereg - (base+1);
}
init_exp(f, expkind.VCALL, lcode.luaK_codeABC(fs, OpCodesI.OP_CALL, base, nparams+1, 2));
lcode.luaK_fixline(fs, line);
fs.freereg = base + 1; /* call remove function and arguments and leaves (unless changed) one result */
};
/*
** {======================================================================
** Expression parsing
** =======================================================================
*/
const primaryexp = function(ls, v) {
/* primaryexp -> NAME | '(' expr ')' */
switch (ls.t.token) {
case char['(']: {
let line = ls.linenumber;
llex.luaX_next(ls);
expr(ls, v);
check_match(ls, char[')'], char['('], line);
lcode.luaK_dischargevars(ls.fs, v);
return;
}
case R.TK_NAME: {
singlevar(ls, v);
return;
}
default: {
llex.luaX_syntaxerror(ls, defs.to_luastring("unexpected symbol", true));
}
}
};
const suffixedexp = function(ls, v) {
/* suffixedexp ->
primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
let fs = ls.fs;
let line = ls.linenumber;
primaryexp(ls, v);
for (;;) {
switch (ls.t.token) {
case char['.']: { /* fieldsel */
fieldsel(ls, v);
break;
}
case char['[']: { /* '[' exp1 ']' */
let key = new expdesc();
lcode.luaK_exp2anyregup(fs, v);
yindex(ls, key);
lcode.luaK_indexed(fs, v, key);
break;
}
case char[':']: { /* ':' NAME funcargs */
let key = new expdesc();
llex.luaX_next(ls);
checkname(ls, key);
lcode.luaK_self(fs, v, key);
funcargs(ls, v, line);
break;
}
case char['(']: case R.TK_STRING: case char['{']: { /* funcargs */
lcode.luaK_exp2nextreg(fs, v);
funcargs(ls, v, line);
break;
}
default: return;
}
}
};
const simpleexp = function(ls, v) {
/* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... |
constructor | FUNCTION body | suffixedexp */
switch (ls.t.token) {
case R.TK_FLT: {
init_exp(v, expkind.VKFLT, 0);
v.u.nval = ls.t.seminfo.r;
break;
}
case R.TK_INT: {
init_exp(v, expkind.VKINT, 0);
v.u.ival = ls.t.seminfo.i;
break;
}
case R.TK_STRING: {
codestring(ls, v, ls.t.seminfo.ts);
break;
}
case R.TK_NIL: {
init_exp(v, expkind.VNIL, 0);
break;
}
case R.TK_TRUE: {
init_exp(v, expkind.VTRUE, 0);
break;
}
case R.TK_FALSE: {
init_exp(v, expkind.VFALSE, 0);
break;
}
case R.TK_DOTS: { /* vararg */
let fs = ls.fs;
check_condition(ls, fs.f.is_vararg, defs.to_luastring("cannot use '...' outside a vararg function", true));
init_exp(v, expkind.VVARARG, lcode.luaK_codeABC(fs, OpCodesI.OP_VARARG, 0, 1, 0));
break;
}
case char['{']: { /* constructor */
constructor(ls, v);
return;
}
case R.TK_FUNCTION: {
llex.luaX_next(ls);
body(ls, v, 0, ls.linenumber);
return;
}
default: {
suffixedexp(ls, v);
return;
}
}
llex.luaX_next(ls);
};
const getunopr = function(op) {
switch (op) {
case R.TK_NOT: return UnOpr.OPR_NOT;
case char['-']: return UnOpr.OPR_MINUS;
case char['~']: return UnOpr.OPR_BNOT;
case char['#']: return UnOpr.OPR_LEN;
default: return UnOpr.OPR_NOUNOPR;
}
};
const getbinopr = function(op) {
switch (op) {
case char['+']: return BinOpr.OPR_ADD;
case char['-']: return BinOpr.OPR_SUB;
case char['*']: return BinOpr.OPR_MUL;
case char['%']: return BinOpr.OPR_MOD;
case char['^']: return BinOpr.OPR_POW;
case char['/']: return BinOpr.OPR_DIV;
case R.TK_IDIV: return BinOpr.OPR_IDIV;
case char['&']: return BinOpr.OPR_BAND;
case char['|']: return BinOpr.OPR_BOR;
case char['~']: return BinOpr.OPR_BXOR;
case R.TK_SHL: return BinOpr.OPR_SHL;
case R.TK_SHR: return BinOpr.OPR_SHR;
case R.TK_CONCAT: return BinOpr.OPR_CONCAT;
case R.TK_NE: return BinOpr.OPR_NE;
case R.TK_EQ: return BinOpr.OPR_EQ;
case char['<']: return BinOpr.OPR_LT;
case R.TK_LE: return BinOpr.OPR_LE;
case char['>']: return BinOpr.OPR_GT;
case R.TK_GE: return BinOpr.OPR_GE;
case R.TK_AND: return BinOpr.OPR_AND;
case R.TK_OR: return BinOpr.OPR_OR;
default: return BinOpr.OPR_NOBINOPR;
}
};
const priority = [ /* ORDER OPR */
{left: 10, right: 10}, {left: 10, right: 10}, /* '+' '-' */
{left: 11, right: 11}, {left: 11, right: 11}, /* '*' '%' */
{left: 14, right: 13}, /* '^' (right associative) */
{left: 11, right: 11}, {left: 11, right: 11}, /* '/' '//' */
{left: 6, right: 6}, {left: 4, right: 4}, {left: 5, right: 5}, /* '&' '|' '~' */
{left: 7, right: 7}, {left: 7, right: 7}, /* '<<' '>>' */
{left: 9, right: 8}, /* '..' (right associative) */
{left: 3, right: 3}, {left: 3, right: 3}, {left: 3, right: 3}, /* ==, <, <= */
{left: 3, right: 3}, {left: 3, right: 3}, {left: 3, right: 3}, /* ~=, >, >= */
{left: 2, right: 2}, {left: 1, right: 1} /* and, or */
];
const UNARY_PRIORITY = 12;
/*
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
** where 'binop' is any binary operator with a priority higher than 'limit'
*/
const subexpr = function(ls, v, limit) {
enterlevel(ls);
let uop = getunopr(ls.t.token);
if (uop !== UnOpr.OPR_NOUNOPR) {
let line = ls.linenumber;
llex.luaX_next(ls);
subexpr(ls, v, UNARY_PRIORITY);
lcode.luaK_prefix(ls.fs, uop, v, line);
} else
simpleexp(ls, v);
/* expand while operators have priorities higher than 'limit' */
let op = getbinopr(ls.t.token);
while (op !== BinOpr.OPR_NOBINOPR && priority[op].left > limit) {
let v2 = new expdesc();
let line = ls.linenumber;
llex.luaX_next(ls);
lcode.luaK_infix(ls.fs, op, v);
/* read sub-expression with higher priority */
let nextop = subexpr(ls, v2, priority[op].right);
lcode.luaK_posfix(ls.fs, op, v, v2, line);
op = nextop;
}
leavelevel(ls);
return op; /* return first untreated operator */
};
const expr = function(ls, v) {
subexpr(ls, v, 0);
};
/* }==================================================================== */
/*
** {======================================================================
** Rules for Statements
** =======================================================================
*/
const block = function(ls) {
/* block -> statlist */
let fs = ls.fs;
let bl = new BlockCnt();
enterblock(fs, bl, 0);
statlist(ls);
leaveblock(fs);
};
/*
** structure to chain all variables in the left-hand side of an
** assignment
*/
class LHS_assign {
constructor() {
this.prev = null;
this.v = new expdesc(); /* variable (global, local, upvalue, or indexed) */
}
}
/*
** check whether, in an assignment to an upvalue/local variable, the
** upvalue/local variable is begin used in a previous assignment to a
** table. If so, save original upvalue/local value in a safe place and
** use this safe copy in the previous assignment.
*/
const check_conflict = function(ls, lh, v) {
let fs = ls.fs;
let extra = fs.freereg; /* eventual position to save local variable */
let conflict = false;
for (; lh; lh = lh.prev) { /* check all previous assignments */
if (lh.v.k === expkind.VINDEXED) { /* assigning to a table? */
/* table is the upvalue/local being assigned now? */
if (lh.v.u.ind.vt === v.k && lh.v.u.ind.t === v.u.info) {
conflict = true;
lh.v.u.ind.vt = expkind.VLOCAL;
lh.v.u.ind.t = extra; /* previous assignment will use safe copy */
}
/* index is the local being assigned? (index cannot be upvalue) */
if (v.k === expkind.VLOCAL && lh.v.u.ind.idx === v.u.info) {
conflict = true;
lh.v.u.ind.idx = extra; /* previous assignment will use safe copy */
}
}
}
if (conflict) {
/* copy upvalue/local value to a temporary (in position 'extra') */
let op = v.k === expkind.VLOCAL ? OpCodesI.OP_MOVE : OpCodesI.OP_GETUPVAL;
lcode.luaK_codeABC(fs, op, extra, v.u.info, 0);
lcode.luaK_reserveregs(fs, 1);
}
};
const assignment = function(ls, lh, nvars) {
let e = new expdesc();
check_condition(ls, vkisvar(lh.v.k), defs.to_luastring("syntax error", true));
if (testnext(ls, char[','])) { /* assignment -> ',' suffixedexp assignment */
let nv = new LHS_assign();
nv.prev = lh;
suffixedexp(ls, nv.v);
if (nv.v.k !== expkind.VINDEXED)
check_conflict(ls, lh, nv.v);
checklimit(ls.fs, nvars + ls.L.nCcalls, llimit.LUAI_MAXCCALLS, defs.to_luastring("JS levels", true));
assignment(ls, nv, nvars + 1);
} else { /* assignment -> '=' explist */
checknext(ls, char['=']);
let nexps = explist(ls, e);
if (nexps !== nvars)
adjust_assign(ls, nvars, nexps, e);
else {
lcode.luaK_setoneret(ls.fs, e); /* close last expression */
lcode.luaK_storevar(ls.fs, lh.v, e);
return; /* avoid default */
}
}
init_exp(e, expkind.VNONRELOC, ls.fs.freereg-1); /* default assignment */
lcode.luaK_storevar(ls.fs, lh.v, e);
};
const cond = function(ls) {
/* cond -> exp */
let v = new expdesc();
expr(ls, v); /* read condition */
if (v.k === expkind.VNIL) v.k = expkind.VFALSE; /* 'falses' are all equal here */
lcode.luaK_goiftrue(ls.fs, v);
return v.f;
};
const gotostat = function(ls, pc) {
let line = ls.linenumber;
let label;
if (testnext(ls, R.TK_GOTO))
label = str_checkname(ls);
else {
llex.luaX_next(ls); /* skip break */
label = lstring.luaS_newliteral(ls.L, "break");
}
let g = newlabelentry(ls, ls.dyd.gt, label, line, pc);
findlabel(ls, g); /* close it if label already defined */
};
/* check for repeated labels on the same block */
const checkrepeated = function(fs, ll, label) {
for (let i = fs.bl.firstlabel; i < ll.n; i++) {
if (eqstr(label, ll.arr[i].name)) {
let msg = lobject.luaO_pushfstring(fs.ls.L,
defs.to_luastring("label '%s' already defined on line %d", true),
label.getstr(), ll.arr[i].line);
semerror(fs.ls, msg);
}
}
};
/* skip no-op statements */
const skipnoopstat = function(ls) {
while (ls.t.token === char[';'] || ls.t.token === R.TK_DBCOLON)
statement(ls);
};
const labelstat = function(ls, label, line) {
/* label -> '::' NAME '::' */
let fs = ls.fs;
let ll = ls.dyd.label;
let l; /* index of new label being created */
checkrepeated(fs, ll, label); /* check for repeated labels */
checknext(ls, R.TK_DBCOLON); /* skip double colon */
/* create new entry for this label */
l = newlabelentry(ls, ll, label, line, lcode.luaK_getlabel(fs));
skipnoopstat(ls); /* skip other no-op statements */
if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
/* assume that locals are already out of scope */
ll.arr[l].nactvar = fs.bl.nactvar;
}
findgotos(ls, ll.arr[l]);
};
const whilestat = function(ls, line) {
/* whilestat -> WHILE cond DO block END */
let fs = ls.fs;
let bl = new BlockCnt();
llex.luaX_next(ls); /* skip WHILE */
let whileinit = lcode.luaK_getlabel(fs);
let condexit = cond(ls);
enterblock(fs, bl, 1);
checknext(ls, R.TK_DO);
block(ls);
lcode.luaK_jumpto(fs, whileinit);
check_match(ls, R.TK_END, R.TK_WHILE, line);
leaveblock(fs);
lcode.luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
};
const repeatstat = function(ls, line) {
/* repeatstat -> REPEAT block UNTIL cond */
let fs = ls.fs;
let repeat_init = lcode.luaK_getlabel(fs);
let bl1 = new BlockCnt();
let bl2 = new BlockCnt();
enterblock(fs, bl1, 1); /* loop block */
enterblock(fs, bl2, 0); /* scope block */
llex.luaX_next(ls); /* skip REPEAT */
statlist(ls);
check_match(ls, R.TK_UNTIL, R.TK_REPEAT, line);
let condexit = cond(ls); /* read condition (inside scope block) */
if (bl2.upval) /* upvalues? */
lcode.luaK_patchclose(fs, condexit, bl2.nactvar);
leaveblock(fs); /* finish scope */
lcode.luaK_patchlist(fs, condexit, repeat_init); /* close the loop */
leaveblock(fs); /* finish loop */
};
const exp1 = function(ls) {
let e = new expdesc();
expr(ls, e);
lcode.luaK_exp2nextreg(ls.fs, e);
assert(e.k === expkind.VNONRELOC);
let reg = e.u.info;
return reg;
};
const forbody = function(ls, base, line, nvars, isnum) {
/* forbody -> DO block */
let bl = new BlockCnt();
let fs = ls.fs;
let endfor;
adjustlocalvars(ls, 3); /* control variables */
checknext(ls, R.TK_DO);
let prep = isnum ? lcode.luaK_codeAsBx(fs, OpCodesI.OP_FORPREP, base, lcode.NO_JUMP) : lcode.luaK_jump(fs);
enterblock(fs, bl, 0); /* scope for declared variables */
adjustlocalvars(ls, nvars);
lcode.luaK_reserveregs(fs, nvars);
block(ls);
leaveblock(fs); /* end of scope for declared variables */
lcode.luaK_patchtohere(fs, prep);
if (isnum) /* end of scope for declared variables */
endfor = lcode.luaK_codeAsBx(fs, OpCodesI.OP_FORLOOP, base, lcode.NO_JUMP);
else { /* generic for */
lcode.luaK_codeABC(fs, OpCodesI.OP_TFORCALL, base, 0, nvars);
lcode.luaK_fixline(fs, line);
endfor = lcode.luaK_codeAsBx(fs, OpCodesI.OP_TFORLOOP, base + 2, lcode.NO_JUMP);
}
lcode.luaK_patchlist(fs, endfor, prep + 1);
lcode.luaK_fixline(fs, line);
};
const fornum = function(ls, varname, line) {
/* fornum -> NAME = exp1,exp1[,exp1] forbody */
let fs = ls.fs;
let base = fs.freereg;
new_localvarliteral(ls, "(for index)");
new_localvarliteral(ls, "(for limit)");
new_localvarliteral(ls, "(for step)");
new_localvar(ls, varname);
checknext(ls, char['=']);
exp1(ls); /* initial value */
checknext(ls, char[',']);
exp1(ls); /* limit */
if (testnext(ls, char[',']))
exp1(ls); /* optional step */
else { /* default step = 1 */
lcode.luaK_codek(fs, fs.freereg, lcode.luaK_intK(fs, 1));
lcode.luaK_reserveregs(fs, 1);
}
forbody(ls, base, line, 1, 1);
};
const forlist = function(ls, indexname) {
/* forlist -> NAME {,NAME} IN explist forbody */
let fs = ls.fs;
let e = new expdesc();
let nvars = 4; /* gen, state, control, plus at least one declared var */
let base = fs.freereg;
/* create control variables */
new_localvarliteral(ls, "(for generator)");
new_localvarliteral(ls, "(for state)");
new_localvarliteral(ls, "(for control)");
/* create declared variables */
new_localvar(ls, indexname);
while (testnext(ls, char[','])) {
new_localvar(ls, str_checkname(ls));
nvars++;
}
checknext(ls, R.TK_IN);
let line = ls.linenumber;
adjust_assign(ls, 3, explist(ls, e), e);
lcode.luaK_checkstack(fs, 3); /* extra space to call generator */
forbody(ls, base, line, nvars - 3, 0);
};
const forstat = function(ls, line) {
/* forstat -> FOR (fornum | forlist) END */
let fs = ls.fs;
let bl = new BlockCnt();
enterblock(fs, bl, 1); /* scope for loop and control variables */
llex.luaX_next(ls); /* skip 'for' */
let varname = str_checkname(ls); /* first variable name */
switch (ls.t.token) {
case char['=']: fornum(ls, varname, line); break;
case char[',']: case R.TK_IN: forlist(ls, varname); break;
default: llex.luaX_syntaxerror(ls, defs.to_luastring("'=' or 'in' expected", true));
}
check_match(ls, R.TK_END, R.TK_FOR, line);
leaveblock(fs); /* loop scope ('break' jumps to this point) */
};
const test_then_block = function(ls, escapelist) {
/* test_then_block -> [IF | ELSEIF] cond THEN block */
let bl = new BlockCnt();
let fs = ls.fs;
let v = new expdesc();
let jf; /* instruction to skip 'then' code (if condition is false) */
llex.luaX_next(ls); /* skip IF or ELSEIF */
expr(ls, v); /* read condition */
checknext(ls, R.TK_THEN);
if (ls.t.token === R.TK_GOTO || ls.t.token === R.TK_BREAK) {
lcode.luaK_goiffalse(ls.fs, v); /* will jump to label if condition is true */
enterblock(fs, bl, false); /* must enter block before 'goto' */
gotostat(ls, v.t); /* handle goto/break */
while (testnext(ls, char[';'])) {} /* skip colons */
if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
leaveblock(fs);
return escapelist; /* and that is it */
} else /* must skip over 'then' part if condition is false */
jf = lcode.luaK_jump(fs);
} else { /* regular case (not goto/break) */
lcode.luaK_goiftrue(ls.fs, v); /* skip over block if condition is false */
enterblock(fs, bl, false);
jf = v.f;
}
statlist(ls); /* 'then' part */
leaveblock(fs);
if (ls.t.token === R.TK_ELSE || ls.t.token === R.TK_ELSEIF) /* followed by 'else'/'elseif'? */
escapelist = lcode.luaK_concat(fs, escapelist, lcode.luaK_jump(fs)); /* must jump over it */
lcode.luaK_patchtohere(fs, jf);
return escapelist;
};
const ifstat = function(ls, line) {
/* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
let fs = ls.fs;
let escapelist = lcode.NO_JUMP; /* exit list for finished parts */
escapelist = test_then_block(ls, escapelist); /* IF cond THEN block */
while (ls.t.token === R.TK_ELSEIF)
escapelist = test_then_block(ls, escapelist); /* ELSEIF cond THEN block */
if (testnext(ls, R.TK_ELSE))
block(ls); /* 'else' part */
check_match(ls, R.TK_END, R.TK_IF, line);
lcode.luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */
};
const localfunc = function(ls) {
let b = new expdesc();
let fs = ls.fs;
new_localvar(ls, str_checkname(ls)); /* new local variable */
adjustlocalvars(ls, 1); /* enter its scope */
body(ls, b, 0, ls.linenumber); /* function created in next register */
/* debug information will only see the variable after this point! */
getlocvar(fs, b.u.info).startpc = fs.pc;
};
const localstat = function(ls) {
/* stat -> LOCAL NAME {',' NAME} ['=' explist] */
let nvars = 0;
let nexps;
let e = new expdesc();
do {
new_localvar(ls, str_checkname(ls));
nvars++;
} while (testnext(ls, char[',']));
if (testnext(ls, char['=']))
nexps = explist(ls, e);
else {
e.k = expkind.VVOID;
nexps = 0;
}
adjust_assign(ls, nvars, nexps, e);
adjustlocalvars(ls, nvars);
};
const funcname = function(ls, v) {
/* funcname -> NAME {fieldsel} [':' NAME] */
let ismethod = 0;
singlevar(ls, v);
while (ls.t.token === char['.'])
fieldsel(ls, v);
if (ls.t.token === char[':']) {
ismethod = 1;
fieldsel(ls, v);
}
return ismethod;
};
const funcstat = function(ls, line) {
/* funcstat -> FUNCTION funcname body */
let v = new expdesc();
let b = new expdesc();
llex.luaX_next(ls); /* skip FUNCTION */
let ismethod = funcname(ls, v);
body(ls, b, ismethod, line);
lcode.luaK_storevar(ls.fs, v, b);
lcode.luaK_fixline(ls.fs, line); /* definition "happens" in the first line */
};
const exprstat= function(ls) {
/* stat -> func | assignment */
let fs = ls.fs;
let v = new LHS_assign();
suffixedexp(ls, v.v);
if (ls.t.token === char['='] || ls.t.token === char[',']) { /* stat . assignment ? */
v.prev = null;
assignment(ls, v, 1);
}
else { /* stat -> func */
check_condition(ls, v.v.k === expkind.VCALL, defs.to_luastring("syntax error", true));
lopcodes.SETARG_C(lcode.getinstruction(fs, v.v), 1); /* call statement uses no results */
}
};
const retstat = function(ls) {
/* stat -> RETURN [explist] [';'] */
let fs = ls.fs;
let e = new expdesc();
let first, nret; /* registers with returned values */
if (block_follow(ls, 1) || ls.t.token === char[';'])
first = nret = 0; /* return no values */
else {
nret = explist(ls, e); /* optional return values */
if (hasmultret(e.k)) {
lcode.luaK_setmultret(fs, e);
if (e.k === expkind.VCALL && nret === 1) { /* tail call? */
lopcodes.SET_OPCODE(lcode.getinstruction(fs, e), OpCodesI.OP_TAILCALL);
assert(lcode.getinstruction(fs, e).A === fs.nactvar);
}
first = fs.nactvar;
nret = defs.LUA_MULTRET; /* return all values */
} else {
if (nret === 1) /* only one single value? */
first = lcode.luaK_exp2anyreg(fs, e);
else {
lcode.luaK_exp2nextreg(fs, e); /* values must go to the stack */
first = fs.nactvar; /* return all active values */
assert(nret === fs.freereg - first);
}
}
}
lcode.luaK_ret(fs, first, nret);
testnext(ls, char[';']); /* skip optional semicolon */
};
const statement = function(ls) {
let line = ls.linenumber; /* may be needed for error messages */
enterlevel(ls);
switch(ls.t.token) {
case char[';']: { /* stat -> ';' (empty statement) */
llex.luaX_next(ls); /* skip ';' */
break;
}
case R.TK_IF: { /* stat -> ifstat */
ifstat(ls, line);
break;
}
case R.TK_WHILE: { /* stat -> whilestat */
whilestat(ls, line);
break;
}
case R.TK_DO: { /* stat -> DO block END */
llex.luaX_next(ls); /* skip DO */
block(ls);
check_match(ls, R.TK_END, R.TK_DO, line);
break;
}
case R.TK_FOR: { /* stat -> forstat */
forstat(ls, line);
break;
}
case R.TK_REPEAT: { /* stat -> repeatstat */
repeatstat(ls, line);
break;
}
case R.TK_FUNCTION: { /* stat -> funcstat */
funcstat(ls, line);
break;
}
case R.TK_LOCAL: { /* stat -> localstat */
llex.luaX_next(ls); /* skip LOCAL */
if (testnext(ls, R.TK_FUNCTION)) /* local function? */
localfunc(ls);
else
localstat(ls);
break;
}
case R.TK_DBCOLON: { /* stat -> label */
llex.luaX_next(ls); /* skip double colon */
labelstat(ls, str_checkname(ls), line);
break;
}
case R.TK_RETURN: { /* skip double colon */
llex.luaX_next(ls); /* skip RETURN */
retstat(ls);
break;
}
case R.TK_BREAK: /* stat -> breakstat */
case R.TK_GOTO: { /* stat -> 'goto' NAME */
gotostat(ls, lcode.luaK_jump(ls.fs));
break;
}
default: { /* stat -> func | assignment */
exprstat(ls);
break;
}
}
assert(ls.fs.f.maxstacksize >= ls.fs.freereg && ls.fs.freereg >= ls.fs.nactvar);
ls.fs.freereg = ls.fs.nactvar; /* free registers */
leavelevel(ls);
};
/*
** compiles the main function, which is a regular vararg function with an
** upvalue named LUA_ENV
*/
const mainfunc = function(ls, fs) {
let bl = new BlockCnt();
let v = new expdesc();
open_func(ls, fs, bl);
fs.f.is_vararg = true; /* main function is always declared vararg */
init_exp(v, expkind.VLOCAL, 0); /* create and... */
newupvalue(fs, ls.envn, v); /* ...set environment upvalue */
llex.luaX_next(ls); /* read first token */
statlist(ls); /* parse main body */
check(ls, R.TK_EOS);
close_func(ls);
};
const luaY_parser = function(L, z, buff, dyd, name, firstchar) {
let lexstate = new llex.LexState();
let funcstate = new FuncState();
let cl = lfunc.luaF_newLclosure(L, 1); /* create main closure */
ldo.luaD_inctop(L);
L.stack[L.top-1].setclLvalue(cl);
lexstate.h = ltable.luaH_new(L); /* create table for scanner */
ldo.luaD_inctop(L);
L.stack[L.top-1].sethvalue(lexstate.h);
funcstate.f = cl.p = new Proto(L);
funcstate.f.source = lstring.luaS_new(L, name);
lexstate.buff = buff;
lexstate.dyd = dyd;
dyd.actvar.n = dyd.gt.n = dyd.label.n = 0;
llex.luaX_setinput(L, lexstate, z, funcstate.f.source, firstchar);
mainfunc(lexstate, funcstate);
assert(!funcstate.prev && funcstate.nups === 1 && !lexstate.fs);
/* all scopes should be correctly finished */
assert(dyd.actvar.n === 0 && dyd.gt.n === 0 && dyd.label.n === 0);
delete L.stack[--L.top]; /* remove scanner's table */
return cl; /* closure is on the stack, too */
};
module.exports.Dyndata = Dyndata;
module.exports.expkind = expkind;
module.exports.expdesc = expdesc;
module.exports.luaY_parser = luaY_parser;
module.exports.vkisinreg = vkisinreg;
/***/ }),
/* 56 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const defs = __webpack_require__(2);
const ldebug = __webpack_require__(23);
const ldo = __webpack_require__(13);
const ljstype = __webpack_require__(54);
const lobject = __webpack_require__(7);
const lstring = __webpack_require__(17);
const ltable = __webpack_require__(16);
const llimit = __webpack_require__(10);
const lzio = __webpack_require__(36);
const TS = defs.thread_status;
const char = defs.char;
const FIRST_RESERVED = 257;
const RESERVED = {
/* terminal symbols denoted by reserved words */
TK_AND: FIRST_RESERVED,
TK_BREAK: FIRST_RESERVED + 1,
TK_DO: FIRST_RESERVED + 2,
TK_ELSE: FIRST_RESERVED + 3,
TK_ELSEIF: FIRST_RESERVED + 4,
TK_END: FIRST_RESERVED + 5,
TK_FALSE: FIRST_RESERVED + 6,
TK_FOR: FIRST_RESERVED + 7,
TK_FUNCTION: FIRST_RESERVED + 8,
TK_GOTO: FIRST_RESERVED + 9,
TK_IF: FIRST_RESERVED + 10,
TK_IN: FIRST_RESERVED + 11,
TK_LOCAL: FIRST_RESERVED + 12,
TK_NIL: FIRST_RESERVED + 13,
TK_NOT: FIRST_RESERVED + 14,
TK_OR: FIRST_RESERVED + 15,
TK_REPEAT: FIRST_RESERVED + 16,
TK_RETURN: FIRST_RESERVED + 17,
TK_THEN: FIRST_RESERVED + 18,
TK_TRUE: FIRST_RESERVED + 19,
TK_UNTIL: FIRST_RESERVED + 20,
TK_WHILE: FIRST_RESERVED + 21,
/* other terminal symbols */
TK_IDIV: FIRST_RESERVED + 22,
TK_CONCAT: FIRST_RESERVED + 23,
TK_DOTS: FIRST_RESERVED + 24,
TK_EQ: FIRST_RESERVED + 25,
TK_GE: FIRST_RESERVED + 26,
TK_LE: FIRST_RESERVED + 27,
TK_NE: FIRST_RESERVED + 28,
TK_SHL: FIRST_RESERVED + 29,
TK_SHR: FIRST_RESERVED + 30,
TK_DBCOLON: FIRST_RESERVED + 31,
TK_EOS: FIRST_RESERVED + 32,
TK_FLT: FIRST_RESERVED + 33,
TK_INT: FIRST_RESERVED + 34,
TK_NAME: FIRST_RESERVED + 35,
TK_STRING: FIRST_RESERVED + 36
};
const R = RESERVED;
const luaX_tokens = [
"and", "break", "do", "else", "elseif",
"end", "false", "for", "function", "goto", "if",
"in", "local", "nil", "not", "or", "repeat",
"return", "then", "true", "until", "while",
"//", "..", "...", "==", ">=", "<=", "~=",
"<<", ">>", "::", "<eof>",
"<number>", "<integer>", "<name>", "<string>"
];
class SemInfo {
constructor() {
this.r = NaN;
this.i = NaN;
this.ts = null;
}
}
class Token {
constructor() {
this.token = NaN;
this.seminfo = new SemInfo();
}
}
/* state of the lexer plus state of the parser when shared by all
functions */
class LexState {
constructor() {
this.current = NaN; /* current character (charint) */
this.linenumber = NaN; /* input line counter */
this.lastline = NaN; /* line of last token 'consumed' */
this.t = new Token(); /* current token */
this.lookahead = new Token(); /* look ahead token */
this.fs = null; /* current function (parser) */
this.L = null;
this.z = null; /* input stream */
this.buff = null; /* buffer for tokens */
this.h = null; /* to reuse strings */
this.dyd = null; /* dynamic structures used by the parser */
this.source = null; /* current source name */
this.envn = null; /* environment variable name */
}
}
const save = function(ls, c) {
let b = ls.buff;
if (b.n + 1 > b.buffer.length) {
if (b.buffer.length >= llimit.MAX_INT/2)
lexerror(ls, defs.to_luastring("lexical element too long", true), 0);
}
b.buffer[b.n++] = c < 0 ? 255 + c + 1 : c;
};
const luaX_token2str = function(ls, token) {
if (token < FIRST_RESERVED) { /* single-byte symbols? */
return lobject.luaO_pushfstring(ls.L, defs.to_luastring("'%c'", true), token);
} else {
let s = luaX_tokens[token - FIRST_RESERVED];
if (token < R.TK_EOS) /* fixed format (symbols and reserved words)? */
return lobject.luaO_pushfstring(ls.L, defs.to_luastring("'%s'", true), defs.to_luastring(s));
else /* names, strings, and numerals */
return defs.to_luastring(s);
}
};
const currIsNewline = function(ls) {
return ls.current === char['\n'] || ls.current === char['\r'];
};
const next = function(ls) {
ls.current = ls.z.zgetc();
};
const save_and_next = function(ls) {
save(ls, ls.current);
next(ls);
};
/*
** creates a new string and anchors it in scanner's table so that
** it will not be collected until the end of the compilation
** (by that time it should be anchored somewhere)
*/
const luaX_newstring = function(ls, str) {
let L = ls.L;
let ts = lstring.luaS_new(L, str);
let o = ltable.luaH_set(L, ls.h, new lobject.TValue(defs.CT.LUA_TLNGSTR, ts));
if (o.ttisnil()) { /* not in use yet? */
o.setbvalue(true);
} else { /* string already present */
/* HACK: Workaround lack of ltable 'keyfromval' */
let tpair = ls.h.strong.get(lstring.luaS_hashlongstr(ts));
assert(tpair.value == o);
ts = tpair.key.tsvalue(); /* re-use value previously stored */
}
return ts;
};
/*
** increment line number and skips newline sequence (any of
** \n, \r, \n\r, or \r\n)
*/
const inclinenumber = function(ls) {
let old = ls.current;
assert(currIsNewline(ls));
next(ls); /* skip '\n' or '\r' */
if (currIsNewline(ls) && ls.current !== old)
next(ls); /* skip '\n\r' or '\r\n' */
if (++ls.linenumber >= llimit.MAX_INT)
lexerror(ls, defs.to_luastring("chunk has too many lines", true), 0);
};
const luaX_setinput = function(L, ls, z, source, firstchar) {
ls.t = {
token: 0,
seminfo: new SemInfo()
};
ls.L = L;
ls.current = firstchar;
ls.lookahead = {
token: R.TK_EOS,
seminfo: new SemInfo()
};
ls.z = z;
ls.fs = null;
ls.linenumber = 1;
ls.lastline = 1;
ls.source = source;
ls.envn = lstring.luaS_newliteral(L, "_ENV");
};
const check_next1 = function(ls, c) {
if (ls.current === c.charCodeAt(0)) {
next(ls);
return true;
}
return false;
};
/*
** Check whether current char is in set 'set' (with two chars) and
** saves it
*/
const check_next2 = function(ls, set) {
if (ls.current === set[0].charCodeAt(0) || ls.current === set[1].charCodeAt(0)) {
save_and_next(ls);
return true;
}
return false;
};
const read_numeral = function(ls, seminfo) {
let expo = "Ee";
let first = ls.current;
assert(ljstype.lisdigit(ls.current));
save_and_next(ls);
if (first === char['0'] && check_next2(ls, "xX")) /* hexadecimal? */
expo = "Pp";
for (;;) {
if (check_next2(ls, expo)) /* exponent part? */
check_next2(ls, "-+"); /* optional exponent sign */
if (ljstype.lisxdigit(ls.current))
save_and_next(ls);
else if (ls.current === char['.'])
save_and_next(ls);
else break;
}
// save(ls, 0);
let obj = lobject.luaO_str2num(ls.buff.buffer);
if (obj === false) /* format error? */
lexerror(ls, defs.to_luastring("malformed number", true), R.TK_FLT);
if (obj.ttisinteger()) {
seminfo.i = obj.value;
return R.TK_INT;
} else {
assert(obj.ttisfloat());
seminfo.r = obj.value;
return R.TK_FLT;
}
};
const txtToken = function(ls, token) {
switch (token) {
case R.TK_NAME: case R.TK_STRING:
case R.TK_FLT: case R.TK_INT:
// save(ls, 0);
return lobject.luaO_pushfstring(ls.L, defs.to_luastring("'%s'", true), ls.buff.buffer);
default:
return luaX_token2str(ls, token);
}
};
const lexerror = function(ls, msg, token) {
msg = ldebug.luaG_addinfo(ls.L, msg, ls.source, ls.linenumber);
if (token)
lobject.luaO_pushfstring(ls.L, defs.to_luastring("%s near %s"), msg, txtToken(ls, token));
ldo.luaD_throw(ls.L, TS.LUA_ERRSYNTAX);
};
const luaX_syntaxerror = function(ls, msg) {
lexerror(ls, msg, ls.t.token);
};
/*
** skip a sequence '[=*[' or ']=*]'; if sequence is well formed, return
** its number of '='s; otherwise, return a negative number (-1 iff there
** are no '='s after initial bracket)
*/
const skip_sep = function(ls) {
let count = 0;
let s = ls.current;
assert(s === char['['] || s === char[']']);
save_and_next(ls);
while (ls.current === char['=']) {
save_and_next(ls);
count++;
}
return ls.current === s ? count : (-count) - 1;
};
const read_long_string = function(ls, seminfo, sep) {
let line = ls.linenumber; /* initial line (for error message) */
save_and_next(ls); /* skip 2nd '[' */
if (currIsNewline(ls)) /* string starts with a newline? */
inclinenumber(ls); /* skip it */
let skip = false;
for (; !skip ;) {
switch (ls.current) {
case lzio.EOZ: { /* error */
let what = seminfo ? "string" : "comment";
let msg = `unfinished long ${what} (starting at line ${line})`;
lexerror(ls, defs.to_luastring(msg), R.TK_EOS);
break;
}
case char[']']: {
if (skip_sep(ls) === sep) {
save_and_next(ls); /* skip 2nd ']' */
skip = true;
}
break;
}
case char['\n']: case char['\r']: {
save(ls, char['\n']);
inclinenumber(ls);
if (!seminfo) lzio.luaZ_resetbuffer(ls.buff);
break;
}
default: {
if (seminfo) save_and_next(ls);
else next(ls);
}
}
}
if (seminfo)
seminfo.ts = luaX_newstring(ls, ls.buff.buffer.slice(2 + sep, 2 + sep - 2 * (2 + sep)));
};
const esccheck = function(ls, c, msg) {
if (!c) {
if (ls.current !== lzio.EOZ)
save_and_next(ls); /* add current to buffer for error message */
lexerror(ls, msg, R.TK_STRING);
}
};
const gethexa = function(ls) {
save_and_next(ls);
esccheck(ls, ljstype.lisxdigit(ls.current), defs.to_luastring("hexadecimal digit expected", true));
return lobject.luaO_hexavalue(ls.current);
};
const readhexaesc = function(ls) {
let r = gethexa(ls);
r = (r << 4) + gethexa(ls);
lzio.luaZ_buffremove(ls.buff, 2); /* remove saved chars from buffer */
return r;
};
const readutf8desc = function(ls) {
let i = 4; /* chars to be removed: '\', 'u', '{', and first digit */
save_and_next(ls); /* skip 'u' */
esccheck(ls, ls.current === char['{'], defs.to_luastring("missing '{'", true));
let r = gethexa(ls); /* must have at least one digit */
save_and_next(ls);
while (ljstype.lisxdigit(ls.current)) {
i++;
r = (r << 4) + lobject.luaO_hexavalue(ls.current);
esccheck(ls, r <= 0x10FFFF, defs.to_luastring("UTF-8 value too large", true));
save_and_next(ls);
}
esccheck(ls, ls.current === char['}'], defs.to_luastring("missing '}'", true));
next(ls); /* skip '}' */
lzio.luaZ_buffremove(ls.buff, i); /* remove saved chars from buffer */
return r;
};
const utf8esc = function(ls) {
let u = lobject.luaO_utf8esc(readutf8desc(ls));
let buff = u.buff;
for (let n = u.n; n > 0; n--) /* add 'buff' to string */
save(ls, buff[lobject.UTF8BUFFSZ - n]);
};
const readdecesc = function(ls) {
let r = 0; /* result accumulator */
let i;
for (i = 0; i < 3 && ljstype.lisdigit(ls.current); i++) { /* read up to 3 digits */
r = 10 * r + ls.current - char['0'];
save_and_next(ls);
}
esccheck(ls, r <= 255, defs.to_luastring("decimal escape too large", true));
lzio.luaZ_buffremove(ls.buff, i); /* remove read digits from buffer */
return r;
};
const read_string = function(ls, del, seminfo) {
save_and_next(ls); /* keep delimiter (for error messages) */
while (ls.current !== del) {
switch (ls.current) {
case lzio.EOZ:
lexerror(ls, defs.to_luastring("unfinished string", true), R.TK_EOS);
break;
case char['\n']:
case char['\r']:
lexerror(ls, defs.to_luastring("unfinished string", true), R.TK_STRING);
break;
case char['\\']: { /* escape sequences */
save_and_next(ls); /* keep '\\' for error messages */
let will;
let c;
switch(ls.current) {
case char['a']: c = 7 /* \a isn't valid JS */; will = 'read_save'; break;
case char['b']: c = char['\b']; will = 'read_save'; break;
case char['f']: c = char['\f']; will = 'read_save'; break;
case char['n']: c = char['\n']; will = 'read_save'; break;
case char['r']: c = char['\r']; will = 'read_save'; break;
case char['t']: c = char['\t']; will = 'read_save'; break;
case char['v']: c = char['\v']; will = 'read_save'; break;
case char['x']: c = readhexaesc(ls); will = 'read_save'; break;
case char['u']: utf8esc(ls); will = 'no_save'; break;
case char['\n']: case char['\r']:
inclinenumber(ls); c = char['\n']; will = 'only_save'; break;
case char['\\']: case char['\"']: case char['\'']:
c = ls.current; will = 'read_save'; break;
case lzio.EOZ: will = 'no_save'; break; /* will raise an error next loop */
case char['z']: { /* zap following span of spaces */
lzio.luaZ_buffremove(ls.buff, 1); /* remove '\\' */
next(ls); /* skip the 'z' */
while (ljstype.lisspace(ls.current)) {
if (currIsNewline(ls)) inclinenumber(ls);
else next(ls);
}
will = 'no_save'; break;
}
default: {
esccheck(ls, ljstype.lisdigit(ls.current), defs.to_luastring("invalid escape sequence", true));
c = readdecesc(ls); /* digital escape '\ddd' */
will = 'only_save'; break;
}
}
if (will === 'read_save')
next(ls);
if (will === 'read_save' || will === 'only_save') {
lzio.luaZ_buffremove(ls.buff, 1); /* remove '\\' */
save(ls, c);
}
break;
}
default:
save_and_next(ls);
}
}
save_and_next(ls); /* skip delimiter */
seminfo.ts = luaX_newstring(ls, ls.buff.buffer.slice(1, ls.buff.n-1));
};
const token_to_index = Object.create(null); /* don't want to return true for e.g. 'hasOwnProperty' */
luaX_tokens.forEach((e, i)=>token_to_index[lstring.luaS_hash(defs.to_luastring(e))] = i);
const isreserved = function(w) {
let kidx = token_to_index[lstring.luaS_hashlongstr(w)];
return kidx !== void 0 && kidx <= 22;
};
const llex = function(ls, seminfo) {
lzio.luaZ_resetbuffer(ls.buff);
for (;;) {
assert(typeof ls.current == "number");
switch (ls.current) {
case char['\n']: case char['\r']: { /* line breaks */
inclinenumber(ls);
break;
}
case char[' ']: case char['\f']: case char['\t']: case char['\v']: { /* spaces */
next(ls);
break;
}
case char['-']: { /* '-' or '--' (comment) */
next(ls);
if (ls.current !== char['-']) return char['-'];
/* else is a comment */
next(ls);
if (ls.current === char['[']) { /* long comment? */
let sep = skip_sep(ls);
lzio.luaZ_resetbuffer(ls.buff); /* 'skip_sep' may dirty the buffer */
if (sep >= 0) {
read_long_string(ls, null, sep); /* skip long comment */
lzio.luaZ_resetbuffer(ls.buff); /* previous call may dirty the buff. */
break;
}
}
/* else short comment */
while (!currIsNewline(ls) && ls.current !== lzio.EOZ)
next(ls); /* skip until end of line (or end of file) */
break;
}
case char['[']: { /* long string or simply '[' */
let sep = skip_sep(ls);
if (sep >= 0) {
read_long_string(ls, seminfo, sep);
return R.TK_STRING;
} else if (sep !== -1) /* '[=...' missing second bracket */
lexerror(ls, defs.to_luastring("invalid long string delimiter", true), R.TK_STRING);
return char['['];
}
case char['=']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_EQ;
else return char['='];
}
case char['<']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_LE;
else if (check_next1(ls, '<')) return R.TK_SHL;
else return char['<'];
}
case char['>']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_GE;
else if (check_next1(ls, '>')) return R.TK_SHR;
else return char['>'];
}
case char['/']: {
next(ls);
if (check_next1(ls, '/')) return R.TK_IDIV;
else return char['/'];
}
case char['~']: {
next(ls);
if (check_next1(ls, '=')) return R.TK_NE;
else return char['~'];
}
case char[':']: {
next(ls);
if (check_next1(ls, ':')) return R.TK_DBCOLON;
else return char[':'];
}
case char['"']: case char['\'']: { /* short literal strings */
read_string(ls, ls.current, seminfo);
return R.TK_STRING;
}
case char['.']: { /* '.', '..', '...', or number */
save_and_next(ls);
if (check_next1(ls, '.')) {
if (check_next1(ls, '.'))
return R.TK_DOTS; /* '...' */
else return R.TK_CONCAT; /* '..' */
}
else if (!ljstype.lisdigit(ls.current)) return char['.'];
else return read_numeral(ls, seminfo);
}
case char['0']: case char['1']: case char['2']: case char['3']: case char['4']:
case char['5']: case char['6']: case char['7']: case char['8']: case char['9']: {
return read_numeral(ls, seminfo);
}
case lzio.EOZ: {
return R.TK_EOS;
}
default: {
if (ljstype.lislalpha(ls.current)) { /* identifier or reserved word? */
do {
save_and_next(ls);
} while (ljstype.lislalnum(ls.current));
let ts = luaX_newstring(ls, ls.buff.buffer);
seminfo.ts = ts;
let kidx = token_to_index[lstring.luaS_hashlongstr(ts)];
if (kidx !== void 0 && kidx <= 22) /* reserved word? */
return kidx + FIRST_RESERVED;
else
return R.TK_NAME;
} else { /* single-char tokens (+ - / ...) */
let c = ls.current;
next(ls);
return c;
}
}
}
}
};
const luaX_next = function(ls) {
ls.lastline = ls.linenumber;
if (ls.lookahead.token !== R.TK_EOS) { /* is there a look-ahead token? */
ls.t.token = ls.lookahead.token; /* use this one */
ls.t.seminfo.i = ls.lookahead.seminfo.i;
ls.t.seminfo.r = ls.lookahead.seminfo.r;
ls.t.seminfo.ts = ls.lookahead.seminfo.ts; // TODO ?
ls.lookahead.token = R.TK_EOS; /* and discharge it */
} else
ls.t.token = llex(ls, ls.t.seminfo); /* read next token */
};
const luaX_lookahead = function(ls) {
assert(ls.lookahead.token === R.TK_EOS);
ls.lookahead.token = llex(ls, ls.lookahead.seminfo);
return ls.lookahead.token;
};
module.exports.FIRST_RESERVED = FIRST_RESERVED;
module.exports.LexState = LexState;
module.exports.RESERVED = RESERVED;
module.exports.isreserved = isreserved;
module.exports.luaX_lookahead = luaX_lookahead;
module.exports.luaX_newstring = luaX_newstring;
module.exports.luaX_next = luaX_next;
module.exports.luaX_setinput = luaX_setinput;
module.exports.luaX_syntaxerror = luaX_syntaxerror;
module.exports.luaX_token2str = luaX_token2str;
module.exports.luaX_tokens = luaX_tokens;
/***/ }),
/* 57 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*jshint esversion: 6 */
const lua = __webpack_require__(4);
const linit = __webpack_require__(88);
const LUA_VERSUFFIX = "_" + lua.LUA_VERSION_MAJOR + "_" + lua.LUA_VERSION_MINOR;
module.exports.LUA_VERSUFFIX = LUA_VERSUFFIX;
const LUA_COLIBNAME = "coroutine";
module.exports.LUA_COLIBNAME = LUA_COLIBNAME;
module.exports.luaopen_coroutine = __webpack_require__(58).luaopen_coroutine;
const LUA_TABLIBNAME = "table";
module.exports.LUA_TABLIBNAME = LUA_TABLIBNAME;
module.exports.luaopen_table = __webpack_require__(61).luaopen_table;
if (false) {
const LUA_IOLIBNAME = "io";
module.exports.LUA_IOLIBNAME = LUA_IOLIBNAME;
module.exports.luaopen_io = require("./liolib.js").luaopen_io;
}
const LUA_OSLIBNAME = "os";
module.exports.LUA_OSLIBNAME = LUA_OSLIBNAME;
module.exports.luaopen_os = __webpack_require__(64).luaopen_os;
const LUA_STRLIBNAME = "string";
module.exports.LUA_STRLIBNAME = LUA_STRLIBNAME;
module.exports.luaopen_string = __webpack_require__(60).luaopen_string;
const LUA_UTF8LIBNAME = "utf8";
module.exports.LUA_UTF8LIBNAME = LUA_UTF8LIBNAME;
module.exports.luaopen_utf8 = __webpack_require__(62).luaopen_utf8;
const LUA_BITLIBNAME = "bit32";
module.exports.LUA_BITLIBNAME = LUA_BITLIBNAME;
// module.exports.luaopen_bit32 = require("./lbitlib.js").luaopen_bit32;
const LUA_MATHLIBNAME = "math";
module.exports.LUA_MATHLIBNAME = LUA_MATHLIBNAME;
module.exports.luaopen_math = __webpack_require__(59).luaopen_math;
const LUA_DBLIBNAME = "debug";
module.exports.LUA_DBLIBNAME = LUA_DBLIBNAME;
module.exports.luaopen_debug = __webpack_require__(63).luaopen_debug;
const LUA_LOADLIBNAME = "package";
module.exports.LUA_LOADLIBNAME = LUA_LOADLIBNAME;
module.exports.luaopen_package = __webpack_require__(65).luaopen_package;
module.exports.luaL_openlibs = linit.luaL_openlibs;
/***/ }),
/* 58 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const lua = __webpack_require__(4);
const lauxlib = __webpack_require__(11);
const getco = function(L) {
let co = lua.lua_tothread(L, 1);
lauxlib.luaL_argcheck(L, co, 1, lua.to_luastring("thread expected", true));
return co;
};
const auxresume = function(L, co, narg) {
if (!lua.lua_checkstack(co, narg)) {
lua.lua_pushliteral(L, "too many arguments to resume");
return -1; /* error flag */
}
if (lua.lua_status(co) === lua.LUA_OK && lua.lua_gettop(co) === 0) {
lua.lua_pushliteral(L, "cannot resume dead coroutine");
return -1; /* error flag */
}
lua.lua_xmove(L, co, narg);
let status = lua.lua_resume(co, L, narg);
if (status === lua.LUA_OK || status === lua.LUA_YIELD) {
let nres = lua.lua_gettop(co);
if (!lua.lua_checkstack(L, nres + 1)) {
lua.lua_pop(co, nres); /* remove results anyway */
lua.lua_pushliteral(L, "too many results to resume");
return -1; /* error flag */
}
lua.lua_xmove(co, L, nres); /* move yielded values */
return nres;
} else {
lua.lua_xmove(co, L, 1); /* move error message */
return -1; /* error flag */
}
};
const luaB_coresume = function(L) {
let co = getco(L);
let r = auxresume(L, co, lua.lua_gettop(L) - 1);
if (r < 0) {
lua.lua_pushboolean(L, 0);
lua.lua_insert(L, -2);
return 2; /* return false + error message */
} else {
lua.lua_pushboolean(L, 1);
lua.lua_insert(L, -(r + 1));
return r + 1; /* return true + 'resume' returns */
}
};
const luaB_auxwrap = function(L) {
let co = lua.lua_tothread(L, lua.lua_upvalueindex(1));
let r = auxresume(L, co, lua.lua_gettop(L));
if (r < 0) {
if (lua.lua_type(L, -1) === lua.LUA_TSTRING) { /* error object is a string? */
lauxlib.luaL_where(L, 1); /* add extra info */
lua.lua_insert(L, -2);
lua.lua_concat(L, 2);
}
return lua.lua_error(L); /* propagate error */
}
return r;
};
const luaB_cocreate = function(L) {
lauxlib.luaL_checktype(L, 1, lua.LUA_TFUNCTION);
let NL = lua.lua_newthread(L);
lua.lua_pushvalue(L, 1); /* move function to top */
lua.lua_xmove(L, NL, 1); /* move function from L to NL */
return 1;
};
const luaB_cowrap = function(L) {
luaB_cocreate(L);
lua.lua_pushcclosure(L, luaB_auxwrap, 1);
return 1;
};
const luaB_yield = function(L) {
return lua.lua_yield(L, lua.lua_gettop(L));
};
const luaB_costatus = function(L) {
let co = getco(L);
if (L === co) lua.lua_pushliteral(L, "running");
else {
switch (lua.lua_status(co)) {
case lua.LUA_YIELD:
lua.lua_pushliteral(L, "suspended");
break;
case lua.LUA_OK: {
let ar = new lua.lua_Debug();
if (lua.lua_getstack(co, 0, ar) > 0) /* does it have frames? */
lua.lua_pushliteral(L, "normal"); /* it is running */
else if (lua.lua_gettop(co) === 0)
lua.lua_pushliteral(L, "dead");
else
lua.lua_pushliteral(L, "suspended"); /* initial state */
break;
}
default: /* some error occurred */
lua.lua_pushliteral(L, "dead");
break;
}
}
return 1;
};
const luaB_yieldable = function(L) {
lua.lua_pushboolean(L, lua.lua_isyieldable(L));
return 1;
};
const luaB_corunning = function(L) {
lua.lua_pushboolean(L, lua.lua_pushthread(L));
return 2;
};
const co_funcs = {
"create": luaB_cocreate,
"isyieldable": luaB_yieldable,
"resume": luaB_coresume,
"running": luaB_corunning,
"status": luaB_costatus,
"wrap": luaB_cowrap,
"yield": luaB_yield
};
const luaopen_coroutine = function(L) {
lauxlib.luaL_newlib(L, co_funcs);
return 1;
};
module.exports.luaopen_coroutine = luaopen_coroutine;
/***/ }),
/* 59 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const seedrandom = __webpack_require__(46);
const lua = __webpack_require__(4);
const lauxlib = __webpack_require__(11);
const llimit = __webpack_require__(10);
const luaconf = __webpack_require__(22);
var RNG = seedrandom();
const math_randomseed = function(L) {
RNG = seedrandom(Math.abs(lauxlib.luaL_checknumber(L, 1)));
return 0;
};
const math_random = function(L) {
let low, up;
let r = RNG();
switch (lua.lua_gettop(L)) { /* check number of arguments */
case 0:
lua.lua_pushnumber(L, r); /* Number between 0 and 1 */
return 1;
case 1: {
low = 1;
up = lauxlib.luaL_checkinteger(L, 1);
break;
}
case 2: {
low = lauxlib.luaL_checkinteger(L, 1);
up = lauxlib.luaL_checkinteger(L, 2);
break;
}
default: return lauxlib.luaL_error(L, lua.to_luastring("wrong number of arguments", true));
}
/* random integer in the interval [low, up] */
lauxlib.luaL_argcheck(L, low <= up, 1, lua.to_luastring("interval is empty", true));
lauxlib.luaL_argcheck(L, low >= 0 || up <= llimit.MAX_INT + low, 1,
lua.to_luastring("interval too large", true));
r *= (up - low) + 1;
lua.lua_pushinteger(L, Math.floor(r) + low);
return 1;
};
const math_abs = function(L) {
if (lua.lua_isinteger(L, 1)) {
let n = lua.lua_tointeger(L, 1);
if (n < 0) n = (-n)|0;
lua.lua_pushinteger(L, n);
}
else
lua.lua_pushnumber(L, Math.abs(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_sin = function(L) {
lua.lua_pushnumber(L, Math.sin(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_cos = function(L) {
lua.lua_pushnumber(L, Math.cos(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_tan = function(L) {
lua.lua_pushnumber(L, Math.tan(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_asin = function(L) {
lua.lua_pushnumber(L, Math.asin(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_acos = function(L) {
lua.lua_pushnumber(L, Math.acos(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_atan = function(L) {
let y = lauxlib.luaL_checknumber(L, 1);
let x = lauxlib.luaL_optnumber(L, 2, 1);
lua.lua_pushnumber(L, Math.atan2(y, x));
return 1;
};
const math_toint = function(L) {
let n = lua.lua_tointegerx(L, 1);
if (n !== false)
lua.lua_pushinteger(L, n);
else {
lauxlib.luaL_checkany(L, 1);
lua.lua_pushnil(L); /* value is not convertible to integer */
}
return 1;
};
const pushnumint = function(L, d) {
let n = luaconf.lua_numbertointeger(d);
if (n !== false) /* does 'd' fit in an integer? */
lua.lua_pushinteger(L, n); /* result is integer */
else
lua.lua_pushnumber(L, d); /* result is float */
};
const math_floor = function(L) {
if (lua.lua_isinteger(L, 1))
lua.lua_settop(L, 1);
else
pushnumint(L, Math.floor(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_ceil = function(L) {
if (lua.lua_isinteger(L, 1))
lua.lua_settop(L, 1);
else
pushnumint(L, Math.ceil(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_sqrt = function(L) {
lua.lua_pushnumber(L, Math.sqrt(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_ult = function(L) {
let a = lauxlib.luaL_checkinteger(L, 1);
let b = lauxlib.luaL_checkinteger(L, 2);
lua.lua_pushboolean(L, (a >= 0)?(b<0 || a<b):(b<0 && a<b));
return 1;
};
const math_log = function(L) {
let x = lauxlib.luaL_checknumber(L, 1);
let res;
if (lua.lua_isnoneornil(L, 2))
res = Math.log(x);
else {
let base = lauxlib.luaL_checknumber(L, 2);
if (base === 2)
res = Math.log2(x);
else if (base === 10)
res = Math.log10(x);
else
res = Math.log(x)/Math.log(base);
}
lua.lua_pushnumber(L, res);
return 1;
};
const math_exp = function(L) {
lua.lua_pushnumber(L, Math.exp(lauxlib.luaL_checknumber(L, 1)));
return 1;
};
const math_deg = function(L) {
lua.lua_pushnumber(L, lauxlib.luaL_checknumber(L, 1) * (180 / Math.PI));
return 1;
};
const math_rad = function(L) {
lua.lua_pushnumber(L, lauxlib.luaL_checknumber(L, 1) * (Math.PI / 180));
return 1;
};
const math_min = function(L) {
let n = lua.lua_gettop(L); /* number of arguments */
let imin = 1; /* index of current minimum value */
lauxlib.luaL_argcheck(L, n >= 1, 1, lua.to_luastring("value expected", true));
for (let i = 2; i <= n; i++){
if (lua.lua_compare(L, i, imin, lua.LUA_OPLT))
imin = i;
}
lua.lua_pushvalue(L, imin);
return 1;
};
const math_max = function(L) {
let n = lua.lua_gettop(L); /* number of arguments */
let imax = 1; /* index of current minimum value */
lauxlib.luaL_argcheck(L, n >= 1, 1, lua.to_luastring("value expected", true));
for (let i = 2; i <= n; i++){
if (lua.lua_compare(L, imax, i, lua.LUA_OPLT))
imax = i;
}
lua.lua_pushvalue(L, imax);
return 1;
};
const math_type = function(L) {
if (lua.lua_type(L, 1) === lua.LUA_TNUMBER) {
if (lua.lua_isinteger(L, 1))
lua.lua_pushliteral(L, "integer");
else
lua.lua_pushliteral(L, "float");
} else {
lauxlib.luaL_checkany(L, 1);
lua.lua_pushnil(L);
}
return 1;
};
const math_fmod = function(L) {
if (lua.lua_isinteger(L, 1) && lua.lua_isinteger(L, 2)) {
let d = lua.lua_tointeger(L, 2);
/* no special case needed for -1 in javascript */
if (d === 0) {
lauxlib.luaL_argerror(L, 2, lua.to_luastring("zero", true));
} else
lua.lua_pushinteger(L, (lua.lua_tointeger(L, 1) % d)|0);
} else {
let a = lauxlib.luaL_checknumber(L, 1);
let b = lauxlib.luaL_checknumber(L, 2);
lua.lua_pushnumber(L, a%b);
}
return 1;
};
const math_modf = function(L) {
if (lua.lua_isinteger(L, 1)) {
lua.lua_settop(L, 1); /* number is its own integer part */
lua.lua_pushnumber(L, 0); /* no fractional part */
} else {
let n = lauxlib.luaL_checknumber(L, 1);
let ip = n < 0 ? Math.ceil(n) : Math.floor(n);
pushnumint(L, ip);
lua.lua_pushnumber(L, n === ip ? 0 : n - ip);
}
return 2;
};
const mathlib = {
"abs": math_abs,
"acos": math_acos,
"asin": math_asin,
"atan": math_atan,
"ceil": math_ceil,
"cos": math_cos,
"deg": math_deg,
"exp": math_exp,
"floor": math_floor,
"fmod": math_fmod,
"log": math_log,
"max": math_max,
"min": math_min,
"modf": math_modf,
"rad": math_rad,
"random": math_random,
"randomseed": math_randomseed,
"sin": math_sin,
"sqrt": math_sqrt,
"tan": math_tan,
"tointeger": math_toint,
"type": math_type,
"ult": math_ult
};
const luaopen_math = function(L) {
lauxlib.luaL_newlib(L, mathlib);
lua.lua_pushnumber(L, Math.PI);
lua.lua_setfield(L, -2, lua.to_luastring("pi", true));
lua.lua_pushnumber(L, Infinity);
lua.lua_setfield(L, -2, lua.to_luastring("huge", true));
lua.lua_pushinteger(L, llimit.MAX_INT);
lua.lua_setfield(L, -2, lua.to_luastring("maxinteger", true));
lua.lua_pushinteger(L, llimit.MIN_INT);
lua.lua_setfield(L, -2, lua.to_luastring("mininteger", true));
return 1;
};
module.exports.luaopen_math = luaopen_math;
/***/ }),
/* 60 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const assert = __webpack_require__(0);
const sprintf = __webpack_require__(34).sprintf;
const lauxlib = __webpack_require__(11);
const lua = __webpack_require__(4);
const luaconf = __webpack_require__(22);
const llimit = __webpack_require__(10);
const sL_ESC = '%';
const L_ESC = sL_ESC.charCodeAt(0);
/*
** maximum number of captures that a pattern can do during
** pattern-matching. This limit is arbitrary, but must fit in
** an unsigned char.
*/
const LUA_MAXCAPTURES = 32;
// (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX))
const MAXSIZE = 2147483647;
/* Give natural (i.e. strings end at the first \0) length of a string represented by an array of bytes */
const strlen = function(s) {
let len = s.indexOf(0);
return len > -1 ? len : s.length;
};
/* translate a relative string position: negative means back from end */
const posrelat = function(pos, len) {
if (pos >= 0) return pos;
else if (0 - pos > len) return 0;
else return len + pos + 1;
};
const str_sub = function(L) {
let s = lauxlib.luaL_checkstring(L, 1);
let l = s.length;
let start = posrelat(lauxlib.luaL_checkinteger(L, 2), l);
let end = posrelat(lauxlib.luaL_optinteger(L, 3, -1), l);
if (start < 1) start = 1;
if (end > l) end = l;
if (start <= end)
lua.lua_pushstring(L, s.slice(start - 1, (start - 1) + (end - start + 1)));
else lua.lua_pushliteral(L, "");
return 1;
};
const str_len = function(L) {
lua.lua_pushinteger(L, lauxlib.luaL_checkstring(L, 1).length);
return 1;
};
const str_char = function(L) {
let n = lua.lua_gettop(L); /* number of arguments */
let p = [];
for (let i = 1; i <= n; i++) {
let c = lauxlib.luaL_checkinteger(L, i);
lauxlib.luaL_argcheck(L, c >= 0 && c <= 255, "value out of range"); // Strings are 8-bit clean
p.push(c);
}
lua.lua_pushstring(L, p);
return 1;
};
const writer = function(L, b, size, B) {
B.push(...b.slice(0, size));
return 0;
};
const str_dump = function(L) {
let b = [];
let strip = lua.lua_toboolean(L, 2);
lauxlib.luaL_checktype(L, 1, lua.LUA_TFUNCTION);
lua.lua_settop(L, 1);
if (lua.lua_dump(L, writer, b, strip) !== 0)
return lauxlib.luaL_error(L, lua.to_luastring("unable to dump given function"));
lua.lua_pushstring(L, b);
return 1;
};
const SIZELENMOD = luaconf.LUA_NUMBER_FRMLEN.length + 1;
const L_NBFD = 1;
/*
** Add integer part of 'x' to buffer and return new 'x'
*/
const adddigit = function(buff, n, x) {
let d = Math.floor(x); /* get integer part from 'x' */
buff[n] = d < 10 ? d + '0'.charCodeAt(0) : d - 10 + 'a'.charCodeAt(0); /* add to buffer */
return x - d; /* return what is left */
};
const num2straux = function(x) {
/* if 'inf' or 'NaN', format it like '%g' */
if (Object.is(x, Infinity))
return lua.to_luastring('inf', true).slice(0);
else if (Object.is(x, -Infinity))
return lua.to_luastring('-inf', true).slice(0);
else if (Number.isNaN(x))
return lua.to_luastring('nan', true).slice(0);
else if (x === 0) { /* can be -0... */
/* create "0" or "-0" followed by exponent */
let zero = sprintf(luaconf.LUA_NUMBER_FMT + "x0p+0", x);
if (Object.is(x, -0))
zero = "-" + zero;
return lua.to_luastring(zero);
} else {
let buff = [];
let fe = luaconf.frexp(x); /* 'x' fraction and exponent */
let m = fe[0];
let e = fe[1];
let n = 0; /* character count */
if (m < 0) { /* is number negative? */
buff[n++] = '-'.charCodeAt(0); /* add signal */
m = -m; /* make it positive */
}
buff[n++] = '0'.charCodeAt(0);
buff[n++] = 'x'.charCodeAt(0); /* add "0x" */
m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */
e -= L_NBFD; /* this digit goes before the radix point */
if (m > 0) { /* more digits? */
buff[n++] = luaconf.lua_getlocaledecpoint().charCodeAt(0); /* add radix point */
do { /* add as many digits as needed */
m = adddigit(buff, n++, m * 16);
} while (m > 0);
}
let exp = lua.to_luastring(sprintf("p%+d", e));
return buff.concat(exp);
}
};
const lua_number2strx = function(L, fmt, x) {
let buff = num2straux(x);
if (fmt[SIZELENMOD] === 'A'.charCodeAt(0)) {
for (let i = 0; i < buff.length; i++)
buff[i] = String.fromCharCode(buff[i]).toUpperCase().charCodeAt(0);
} else if (fmt[SIZELENMOD] !== 'a'.charCodeAt(0))
lauxlib.luaL_error(L, lua.to_luastring("modifiers for format '%%a'/'%%A' not implemented"));
return buff;
};
/*
** Maximum size of each formatted item. This maximum size is produced
** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.',
** and '\0') + number of decimal digits to represent maxfloat (which
** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra
** expenses", such as locale-dependent stuff)
*/
const MAX_ITEM = 120;// TODO: + l_mathlim(MAX_10_EXP);
/* valid flags in a format specification */
const FLAGS = ["-".charCodeAt(0), "+".charCodeAt(0), " ".charCodeAt(0), "#".charCodeAt(0), "0".charCodeAt(0)];
/*
** maximum size of each format specification (such as "%-099.99d")
*/
const MAX_FORMAT = 32;
// TODO: locale ? and do it better
const isalpha = e => ('a'.charCodeAt(0) <= e && e <= 'z'.charCodeAt(0)) || (e >= 'A'.charCodeAt(0) && e <= 'Z'.charCodeAt(0));
const isdigit = e => '0'.charCodeAt(0) <= e && e <= '9'.charCodeAt(0);
const iscntrl = e => (0x00 <= e && e <= 0x1f) || e === 0x7f;
const isgraph = e => e > 32 && e < 127; // TODO: Will only work for ASCII
const islower = e => /^[a-z]$/.test(String.fromCharCode(e));
const isupper = e => /^[A-Z]$/.test(String.fromCharCode(e));
const isalnum = e => /^[a-zA-Z0-9]$/.test(String.fromCharCode(e));
const ispunct = e => isgraph(e) && !isalnum(e);
const isspace = e => /^\s$/.test(String.fromCharCode(e));
const isxdigit = e => /^[0-9A-Fa-f]$/.test(String.fromCharCode(e));
// Concat 2 arrays by modifying the first one
const concat = function (a1, a2) {
for (let i = 0; i < a2.length; i++)
a1.push(a2[i]);
};
const addquoted = function(b, s) {
b.push('"'.charCodeAt(0));
let len = s.length;
while (len--) {
if (s[0] === '"'.charCodeAt(0) || s[0] === '\\'.charCodeAt(0) || s[0] === '\n'.charCodeAt(0)) {
b.push('\\'.charCodeAt(0));
b.push(s[0]);
} else if (iscntrl(s[0])) {
let buff = [];
if (!isdigit(s[1]))
buff = lua.to_luastring(sprintf("\\%d", s[0]));
else
buff = lua.to_luastring(sprintf("\\%03d", s[0]));
concat(b, buff);
} else
b.push(s[0]);
s = s.slice(1);
}
b.push('"'.charCodeAt(0));
};
/*
** Ensures the 'buff' string uses a dot as the radix character.
*/
const checkdp = function(buff) {
if (buff.indexOf('.'.charCodeAt(0)) < 0) { /* no dot? */
let point = luaconf.lua_getlocaledecpoint().charCodeAt(0); /* try locale point */
let ppoint = buff.indexOf(point);
if (ppoint) buff[ppoint] = '.'; /* change it to a dot */
}
};
const addliteral = function(L, b, arg) {
switch(lua.lua_type(L, arg)) {
case lua.LUA_TSTRING: {
let s = lua.lua_tostring(L, arg);
addquoted(b, s, s.length);
break;
}
case lua.LUA_TNUMBER: {
if (!lua.lua_isinteger(L, arg)) { /* float? */
let n = lua.lua_tonumber(L, arg); /* write as hexa ('%a') */
concat(b, lua_number2strx(L, lua.to_luastring(`%${luaconf.LUA_INTEGER_FRMLEN}a`), n));
checkdp(b); /* ensure it uses a dot */
} else { /* integers */
let n = lua.lua_tointeger(L, arg);
let format = (n === llimit.LUA_MININTEGER) /* corner case? */
? "0x%" + luaconf.LUA_INTEGER_FRMLEN + "x" /* use hexa */
: luaconf.LUA_INTEGER_FMT; /* else use default format */
concat(b, lua.to_luastring(sprintf(format, n)));
}
break;
}
case lua.LUA_TNIL: case lua.LUA_TBOOLEAN: {
concat(b, lauxlib.luaL_tolstring(L, arg));
break;
}
default: {
lauxlib.luaL_argerror(L, arg, lua.to_luastring("value has no literal form", true));
}
}
};
const scanformat = function(L, strfrmt, form) {
let p = strfrmt;
while (p[0] !== 0 && FLAGS.indexOf(p[0]) >= 0) p = p.slice(1); /* skip flags */
if (strfrmt.length - p.length >= FLAGS.length)
lauxlib.luaL_error(L, lua.to_luastring("invalid format (repeated flags)", true));
if (isdigit(p[0])) p = p.slice(1); /* skip width */
if (isdigit(p[0])) p = p.slice(1); /* (2 digits at most) */
if (p[0] === '.'.charCodeAt(0)) {
p = p.slice(1);
if (isdigit(p[0])) p = p.slice(1); /* skip precision */
if (isdigit(p[0])) p = p.slice(1); /* (2 digits at most) */
}
if (isdigit(p[0]))
lauxlib.luaL_error(L, lua.to_luastring("invalid format (width or precision too long)", true));
form[0] = "%".charCodeAt(0);
for (let i = 0; i < strfrmt.length - p.length + 1; i++)
form[i + 1] = strfrmt[i];
// form[strfrmt.length - p.length + 2] = 0;
return {
form: form,
p: p
};
};
/*
** add length modifier into formats
*/
const addlenmod = function(form, lenmod) {
let l = form.length;
let lm = lenmod.length;
let spec = form[l - 1];
for (let i = 0; i < lenmod.length; i++)
form[i + l - 1] = lenmod[i];
form[l + lm - 1] = spec;
// form[l + lm] = 0;
return form;
};
const str_format = function(L) {
let top = lua.lua_gettop(L);
let arg = 1;
let strfrmt = lauxlib.luaL_checkstring(L, arg);
let b = [];
while (strfrmt.length > 0) {
if (strfrmt[0] !== L_ESC) {
b.push(strfrmt[0]);
strfrmt = strfrmt.slice(1);
} else if ((strfrmt = strfrmt.slice(1))[0] === L_ESC) {
b.push(strfrmt[0]);
strfrmt = strfrmt.slice(1);
} else { /* format item */
let form = []; /* to store the format ('%...') */
if (++arg > top)
lauxlib.luaL_argerror(L, arg, lua.to_luastring("no value", true));
let f = scanformat(L, strfrmt, form);
strfrmt = f.p;
form = f.form;
switch (String.fromCharCode(strfrmt[0])) {
case 'c': {
strfrmt = strfrmt.slice(1);
// concat(b, lua.to_luastring(sprintf(String.fromCharCode(...form), lauxlib.luaL_checkinteger(L, arg))));
b.push(lauxlib.luaL_checkinteger(L, arg));
break;
}
case 'd': case 'i':
case 'o': case 'u': case 'x': case 'X': {
strfrmt = strfrmt.slice(1);
let n = lauxlib.luaL_checkinteger(L, arg);
form = addlenmod(form, luaconf.LUA_INTEGER_FRMLEN.split('').map(e => e.charCodeAt(0)));
concat(b, lua.to_luastring(sprintf(String.fromCharCode(...form), n)));
break;
}
case 'a': case 'A': {
strfrmt = strfrmt.slice(1);
form = addlenmod(form, luaconf.LUA_INTEGER_FRMLEN.split('').map(e => e.charCodeAt(0)));
concat(b, lua_number2strx(L, form, lauxlib.luaL_checknumber(L, arg)));
break;
}
case 'e': case 'E': case 'f':
case 'g': case 'G': {
strfrmt = strfrmt.slice(1);
let n = lauxlib.luaL_checknumber(L, arg);
form = addlenmod(form, luaconf.LUA_INTEGER_FRMLEN.split('').map(e => e.charCodeAt(0)));
concat(b, lua.to_luastring(sprintf(String.fromCharCode(...form), n)));
break;
}
case 'q': {
strfrmt = strfrmt.slice(1);
addliteral(L, b, arg);
break;
}
case 's': {
strfrmt = strfrmt.slice(1);
let s = lauxlib.luaL_tolstring(L, arg);
if (form.length <= 2 || form[2] === 0) { /* no modifiers? */
concat(b, s); /* keep entire string */
lua.lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
} else {
lauxlib.luaL_argcheck(L, s.length === strlen(s), arg, lua.to_luastring("string contains zeros", true));
if (form.indexOf('.'.charCodeAt(0)) < 0 && s.length >= 100) {
/* no precision and string is too long to be formatted */
concat(b, s); /* keep entire string */
lua.lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
} else { /* format the string into 'buff' */
// TODO: will fail if s is not valid UTF-8
concat(b, lua.to_luastring(sprintf(String.fromCharCode(...form), lua.to_jsstring(s))));
lua.lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
}
}
break;
}
default: { /* also treat cases 'pnLlh' */
return lauxlib.luaL_error(L, lua.to_luastring("invalid option '%%%c' to 'format'"), strfrmt[0]);
}
}
}
}
lua.lua_pushstring(L, b);
return 1;
};
/* value used for padding */
const LUAL_PACKPADBYTE = 0x00;
/* maximum size for the binary representation of an integer */
const MAXINTSIZE = 16;
const SZINT = 4; // Size of lua_Integer
/* number of bits in a character */
const NB = 8;
/* mask for one character (NB 1's) */
const MC = ((1 << NB) - 1);
const MAXALIGN = 8;
/*
** information to pack/unpack stuff
*/
class Header {
constructor(L) {
this.L = L;
this.islittle = true;
this.maxalign = 1;
}
}
/*
** options for pack/unpack
*/
const KOption = {
Kint: 0, /* signed integers */
Kuint: 1, /* unsigned integers */
Kfloat: 2, /* floating-point numbers */
Kchar: 3, /* fixed-length strings */
Kstring: 4, /* strings with prefixed length */
Kzstr: 5, /* zero-terminated strings */
Kpadding: 6, /* padding */
Kpaddalign: 7, /* padding for alignment */
Knop: 8 /* no-op (configuration or spaces) */
};
const digit = function(c) {
return '0'.charCodeAt(0) <= c && c <= '9'.charCodeAt(0);
};
const getnum = function(fmt, df) {
if (fmt.off >= fmt.s.length || !digit(fmt.s[fmt.off])) /* no number? */
return df; /* return default value */
else {
let a = 0;
do {
a = a * 10 + (fmt.s[fmt.off++] - '0'.charCodeAt(0));
} while (fmt.off < fmt.s.length && digit(fmt.s[fmt.off]) && a <= (MAXSIZE - 9)/10);
return a;
}
};
/*
** Read an integer numeral and raises an error if it is larger
** than the maximum size for integers.
*/
const getnumlimit = function(h, fmt, df) {
let sz = getnum(fmt, df);
if (sz > MAXINTSIZE || sz <= 0)
lauxlib.luaL_error(h.L, lua.to_luastring("integral size (%d) out of limits [1,%d]"), sz, MAXINTSIZE);
return sz;
};
/*
** Read and classify next option. 'size' is filled with option's size.
*/
const getoption = function(h, fmt) {
let r = {
opt: NaN,
size: NaN
};
r.opt = fmt.s[fmt.off++];
r.size = 0; /* default */
switch (r.opt) {
case 'b'.charCodeAt(0): r.size = 1; r.opt = KOption.Kint; return r; // sizeof(char): 1
case 'B'.charCodeAt(0): r.size = 1; r.opt = KOption.Kuint; return r;
case 'h'.charCodeAt(0): r.size = 2; r.opt = KOption.Kint; return r; // sizeof(short): 2
case 'H'.charCodeAt(0): r.size = 2; r.opt = KOption.Kuint; return r;
case 'l'.charCodeAt(0): r.size = 4; r.opt = KOption.Kint; return r; // sizeof(long): 4
case 'L'.charCodeAt(0): r.size = 4; r.opt = KOption.Kuint; return r;
case 'j'.charCodeAt(0): r.size = 4; r.opt = KOption.Kint; return r; // sizeof(lua_Integer): 4
case 'J'.charCodeAt(0): r.size = 4; r.opt = KOption.Kuint; return r;
case 'T'.charCodeAt(0): r.size = 4; r.opt = KOption.Kuint; return r; // sizeof(size_t): 4
case 'f'.charCodeAt(0): r.size = 4; r.opt = KOption.Kfloat; return r; // sizeof(float): 4
case 'd'.charCodeAt(0): r.size = 8; r.opt = KOption.Kfloat; return r; // sizeof(double): 8
case 'n'.charCodeAt(0): r.size = 8; r.opt = KOption.Kfloat; return r; // sizeof(lua_Number): 8
case 'i'.charCodeAt(0): r.size = getnumlimit(h, fmt, 4); r.opt = KOption.Kint; return r; // sizeof(int): 4
case 'I'.charCodeAt(0): r.size = getnumlimit(h, fmt, 4); r.opt = KOption.Kuint; return r;
case 's'.charCodeAt(0): r.size = getnumlimit(h, fmt, 4); r.opt = KOption.Kstring; return r;
case 'c'.charCodeAt(0): {
r.size = getnum(fmt, -1);
if (r.size === -1)
lauxlib.luaL_error(h.L, lua.to_luastring("missing size for format option 'c'"));
r.opt = KOption.Kchar;
return r;
}
case 'z'.charCodeAt(0): r.opt = KOption.Kzstr; return r;
case 'x'.charCodeAt(0): r.size = 1; r.opt = KOption.Kpadding; return r;
case 'X'.charCodeAt(0): r.opt = KOption.Kpaddalign; return r;
case ' '.charCodeAt(0): break;
case '<'.charCodeAt(0): h.islittle = true; break;
case '>'.charCodeAt(0): h.islittle = false; break;
case '='.charCodeAt(0): h.islittle = true; break;
case '!'.charCodeAt(0): h.maxalign = getnumlimit(h, fmt, MAXALIGN); break;
default: lauxlib.luaL_error(h.L, lua.to_luastring("invalid format option '%c'"), r.opt);
}
r.opt = KOption.Knop;
return r;
};
/*
** Read, classify, and fill other details about the next option.
** 'psize' is filled with option's size, 'notoalign' with its
** alignment requirements.
** Local variable 'size' gets the size to be aligned. (Kpadal option
** always gets its full alignment, other options are limited by
** the maximum alignment ('maxalign'). Kchar option needs no alignment
** despite its size.
*/
const getdetails = function(h, totalsize, fmt) {
let r = {
opt: NaN,
size: NaN,
ntoalign: NaN
};
let opt = getoption(h, fmt);
r.size = opt.size;
r.opt = opt.opt;
let align = r.size; /* usually, alignment follows size */
if (r.opt === KOption.Kpaddalign) { /* 'X' gets alignment from following option */
if (fmt.off >= fmt.s.length || fmt.s[fmt.off] === 0)
lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("invalid next option for option 'X'", true));
else {
let o = getoption(h, fmt);
align = o.size;
o = o.opt;
if (o === KOption.Kchar || align === 0)
lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("invalid next option for option 'X'", true));
}
}
if (align <= 1 || r.opt === KOption.Kchar) /* need no alignment? */
r.ntoalign = 0;
else {
if (align > h.maxalign) /* enforce maximum alignment */
align = h.maxalign;
if ((align & (align -1)) !== 0) /* is 'align' not a power of 2? */
lauxlib.luaL_argerror(h.L, 1, lua.to_luastring("format asks for alignment not power of 2", true));
r.ntoalign = (align - (totalsize & (align - 1))) & (align - 1);
}
return r;
};
/*
** Pack integer 'n' with 'size' bytes and 'islittle' endianness.
** The final 'if' handles the case when 'size' is larger than
** the size of a Lua integer, correcting the extra sign-extension
** bytes if necessary (by default they would be zeros).
*/
const packint = function(b, n, islittle, size, neg) {
let buff = new Array(size);
buff[islittle ? 0 : size - 1] = n & MC; /* first byte */
for (let i = 1; i < size; i++) {
n >>= NB;
buff[islittle ? i : size - 1 - i] = n & MC;
}
if (neg && size > SZINT) { /* negative number need sign extension? */
for (let i = SZINT; i < size; i++) /* correct extra bytes */
buff[islittle ? i : size - 1 - i] = MC;
}
b.push(...buff); /* add result to buffer */
};
const packnum = function(b, n, islittle, size) {
let dv = new DataView(new ArrayBuffer(size));
if (size === 4) dv.setFloat32(0, n, islittle);
else dv.setFloat64(0, n, islittle);
for (let i = 0; i < size; i++)
b.push(dv.getUint8(i, islittle));
};
const str_pack = function(L) {
let b = [];
let h = new Header(L);
let fmt = {
s: lauxlib.luaL_checkstring(L, 1), /* format string */
off: 0
};
let arg = 1; /* current argument to pack */
let totalsize = 0; /* accumulate total size of result */
lua.lua_pushnil(L); /* mark to separate arguments from string buffer */
while (fmt.off < fmt.s.length) {
let details = getdetails(h, totalsize, fmt);
let opt = details.opt;
let size = details.size;
let ntoalign = details.ntoalign;
totalsize += ntoalign + size;
while (ntoalign-- > 0)
b.push(LUAL_PACKPADBYTE); /* fill alignment */
arg++;
switch (opt) {
case KOption.Kint: { /* signed integers */
let n = lauxlib.luaL_checkinteger(L, arg);
if (size < SZINT) { /* need overflow check? */
let lim = 1 << (size * 8) - 1;
lauxlib.luaL_argcheck(L, -lim <= n && n < lim, arg, lua.to_luastring("integer overflow", true));
}
packint(b, n, h.islittle, size, n < 0);
break;
}
case KOption.Kuint: { /* unsigned integers */
let n = lauxlib.luaL_checkinteger(L, arg);
if (size < SZINT)
lauxlib.luaL_argcheck(L, (n>>>0) < (1 << (size * NB)), arg, lua.to_luastring("unsigned overflow", true));
packint(b, n>>>0, h.islittle, size, false);
break;
}
case KOption.Kfloat: { /* floating-point options */
let n = lauxlib.luaL_checknumber(L, arg); /* get argument */
packnum(b, n, h.islittle, size);
break;
}
case KOption.Kchar: { /* fixed-size string */
let s = lauxlib.luaL_checkstring(L, arg);
let len = s.length;
lauxlib.luaL_argcheck(L, len <= size, arg, lua.to_luastring("string longer than given size", true));
b.push(...s); /* add string */
while (len++ < size) /* pad extra space */
b.push(LUAL_PACKPADBYTE);
break;
}
case KOption.Kstring: { /* strings with length count */
let s = lauxlib.luaL_checkstring(L, arg);
let len = s.length;
lauxlib.luaL_argcheck(L, size >= 4 /* sizeof(size_t) */ ||
len < (1 << (size * NB)),
arg, lua.to_luastring("string length does not fit in given size", true));
packint(b, len, h.islittle, size, 0); /* pack length */
b.push(...s);
totalsize += len;
break;
}
case KOption.Kzstr: { /* zero-terminated string */
let s = lauxlib.luaL_checkstring(L, arg);
let len = s.length;
lauxlib.luaL_argcheck(L, s.indexOf(0) < 0, arg, lua.to_luastring("strings contains zeros", true));
b.push(...s);
b.push(0); /* add zero at the end */
totalsize += len + 1;
break;
}
case KOption.Kpadding: b.push(LUAL_PACKPADBYTE); /* fall through */
case KOption.Kpaddalign: case KOption.Knop:
arg--; /* undo increment */
break;
}
}
lua.lua_pushstring(L, b);
return 1;
};
const str_reverse = function(L) {
lua.lua_pushstring(L, lauxlib.luaL_checkstring(L, 1).slice(0).reverse());
return 1;
};
const str_lower = function(L) {
// TODO: will fail on invalid UTF-8
lua.lua_pushstring(L, lua.to_luastring(lua.to_jsstring(lauxlib.luaL_checkstring(L, 1)).toLowerCase()));
return 1;
};
const str_upper = function(L) {
// TODO: will fail on invalid UTF-8
lua.lua_pushstring(L, lua.to_luastring(lua.to_jsstring(lauxlib.luaL_checkstring(L, 1)).toUpperCase()));
return 1;
};
const str_rep = function(L) {
let s = lauxlib.luaL_checkstring(L, 1);
let n = lauxlib.luaL_checkinteger(L, 2);
let sep = lauxlib.luaL_optstring(L, 3, []);
if (s.length + sep.length < s.length || s.length + sep.length > MAXSIZE / n) /* may overflow? */
return lauxlib.luaL_error(L, lua.to_luastring("resulting string too large", true));
let r = [];
for (let i = 0; i < n - 1; i++)
r = r.concat(s.concat(sep));
r = r.concat(s);
lua.lua_pushstring(L, n > 0 ? r : []);
return 1;
};
const str_byte = function(L) {
let s = lauxlib.luaL_checkstring(L, 1);
let l = s.length;
let posi = posrelat(lauxlib.luaL_optinteger(L, 2, 1), l);
let pose = posrelat(lauxlib.luaL_optinteger(L, 3, posi), l);
if (posi < 1) posi = 1;
if (pose > l) pose = l;
if (posi > pose) return 0; /* empty interval; return no values */
if (pose - posi >= llimit.MAX_INT) /* arithmetic overflow? */
return lauxlib.luaL_error(L, lua.to_luastring("string slice too long", true));
let n = (pose - posi) + 1;
lauxlib.luaL_checkstack(L, n, lua.to_luastring("string slice too long", true));
for (let i = 0; i < n; i++)
lua.lua_pushinteger(L, s[posi + i - 1]);
return n;
};
const str_packsize = function(L) {
let h = new Header(L);
let fmt = {
s: lauxlib.luaL_checkstring(L, 1),
off: 0
};
let totalsize = 0; /* accumulate total size of result */
while (fmt.off < fmt.s.length) {
let details = getdetails(h, totalsize, fmt);
let opt = details.opt;
let size = details.size;
let ntoalign = details.ntoalign;
size += ntoalign; /* total space used by option */
lauxlib.luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, lua.to_luastring("format result too large", true));
totalsize += size;
switch (opt) {
case KOption.Kstring: /* strings with length count */
case KOption.Kzstr: /* zero-terminated string */
lauxlib.luaL_argerror(L, 1, lua.to_luastring("variable-length format", true));
/* call never return, but to avoid warnings: *//* fall through */
default: break;
}
}
lua.lua_pushinteger(L, totalsize);
return 1;
};
/*
** Unpack an integer with 'size' bytes and 'islittle' endianness.
** If size is smaller than the size of a Lua integer and integer
** is signed, must do sign extension (propagating the sign to the
** higher bits); if size is larger than the size of a Lua integer,
** it must check the unread bytes to see whether they do not cause an
** overflow.
*/
const unpackint = function(L, str, islittle, size, issigned) {
let res = 0;
let limit = size <= SZINT ? size : SZINT;
for (let i = limit - 1; i >= 0; i--) {
res <<= NB;
res |= str[islittle ? i : size - 1 - i];
}
if (size < SZINT) { /* real size smaller than lua_Integer? */
if (issigned) { /* needs sign extension? */
let mask = 1 << (size * NB - 1);
res = ((res ^ mask) - mask); /* do sign extension */
}
} else if (size > SZINT) { /* must check unread bytes */
let mask = !issigned || res >= 0 ? 0 : MC;
for (let i = limit; i < size; i++) {
if (str[islittle ? i : size - 1 - i] !== mask)
lauxlib.luaL_error(L, lua.to_luastring("%d-byte integer does not fit into Lua Integer"), size);
}
}
return res;
};
const unpacknum = function(L, b, islittle, size) {
assert(b.length >= size);
let dv = new DataView(new ArrayBuffer(size));
for (let i = 0; i < size; i++)
dv.setUint8(i, b[i], islittle);
if (size == 4) return dv.getFloat32(0, islittle);
else return dv.getFloat64(0, islittle);
};
const str_unpack = function(L) {
let h = new Header(L);
let fmt = {
s: lauxlib.luaL_checkstring(L, 1),
off: 0
};
let data = lauxlib.luaL_checkstring(L, 2);
let ld = data.length;
let pos = posrelat(lauxlib.luaL_optinteger(L, 3, 1), ld) - 1;
let n = 0; /* number of results */
lauxlib.luaL_argcheck(L, pos <= ld && pos >= 0, 3, lua.to_luastring("initial position out of string", true));
while (fmt.off < fmt.s.length) {
let details = getdetails(h, pos, fmt);
let opt = details.opt;
let size = details.size;
let ntoalign = details.ntoalign;
if (/*ntoalign + size > ~pos ||*/ pos + ntoalign + size > ld)
lauxlib.luaL_argerror(L, 2, lua.to_luastring("data string too short", true));
pos += ntoalign; /* skip alignment */
/* stack space for item + next position */
lauxlib.luaL_checkstack(L, 2, lua.to_luastring("too many results", true));
n++;
switch (opt) {
case KOption.Kint:
case KOption.Kuint: {
let res = unpackint(L, data.slice(pos), h.islittle, size, opt === KOption.Kint);
lua.lua_pushinteger(L, res);
break;
}
case KOption.Kfloat: {
let res = unpacknum(L, data.slice(pos), h.islittle, size);
lua.lua_pushnumber(L, res);
break;
}
case KOption.Kchar: {
lua.lua_pushstring(L, data.slice(pos, pos + size));
break;
}
case KOption.Kstring: {
let len = unpackint(L, data.slice(pos), h.islittle, size, 0);
lauxlib.luaL_argcheck(L, pos + len + size <= ld, 2, lua.to_luastring("data string too short", true));
lua.lua_pushstring(L, data.slice(pos + size, pos + size + len));
pos += len; /* skip string */
break;
}
case KOption.Kzstr: {
let len = data.slice(pos).indexOf(0);
lua.lua_pushstring(L, data.slice(pos, pos + len));
pos += len + 1; /* skip string plus final '\0' */
break;
}
case KOption.Kpaddalign: case KOption.Kpadding: case KOption.Knop:
n--; /* undo increment */
break;
}
pos += size;
}
lua.lua_pushinteger(L, pos + 1); /* next position */
return n + 1;
};
const CAP_UNFINISHED = -1;
const CAP_POSITION = -2;
const MAXCCALLS = 200;
const SPECIALS = ["^".charCodeAt(0), "$".charCodeAt(0), "*".charCodeAt(0), "+".charCodeAt(0), "?".charCodeAt(0), ".".charCodeAt(0), "(".charCodeAt(0), "[".charCodeAt(0), "%".charCodeAt(0), "-".charCodeAt(0)];
class MatchState {
constructor(L) {
this.src = null; /* unmodified source string */
this.src_init = null; /* init of source string */
this.src_end = null; /* end ('\0') of source string */
this.p = null; /* unmodified pattern string */
this.p_end = null; /* end ('\0') of pattern */
this.L = L;
this.matchdepth = NaN; /* control for recursive depth */
this.level = NaN; /* total number of captures (finished or unfinished) */
this.capture = [];
}
}
const check_capture = function(ms, l) {
l = l - '1'.charCodeAt(0);
if (l < 0 || l >= ms.level || ms.capture[l].len === CAP_UNFINISHED)
return lauxlib.luaL_error(ms.L, lua.to_luastring("invalid capture index %%%d"), l + 1);
return l;
};
const capture_to_close = function(ms) {
let level = ms.level;
for (level--; level >= 0; level--)
if (ms.capture[level].len === CAP_UNFINISHED) return level;
return lauxlib.luaL_error(ms.L, lua.to_luastring("invalid pattern capture"));
};
const classend = function(ms, p) {
switch(ms.p[p++]) {
case L_ESC: {
if (p === ms.p_end)
lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (ends with '%%')"));
return p + 1;
}
case '['.charCodeAt(0): {
if (ms.p[p] === '^'.charCodeAt(0)) p++;
do { /* look for a ']' */
if (p === ms.p_end)
lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing ']')"));
if (ms.p[p++] === L_ESC && p < ms.p_end)
p++; /* skip escapes (e.g. '%]') */
} while (ms.p[p] !== ']'.charCodeAt(0));
return p + 1;
}
default: {
return p;
}
}
};
const match_class = function(c, cl) {
let res;
switch (String.fromCharCode(cl).toLowerCase().charCodeAt(0)) {
case 'a'.charCodeAt(0) : res = isalpha(c); break;
case 'c'.charCodeAt(0) : res = iscntrl(c); break;
case 'd'.charCodeAt(0) : res = isdigit(c); break;
case 'g'.charCodeAt(0) : res = isgraph(c); break;
case 'l'.charCodeAt(0) : res = islower(c); break;
case 'p'.charCodeAt(0) : res = ispunct(c); break;
case 's'.charCodeAt(0) : res = isspace(c); break;
case 'u'.charCodeAt(0) : res = isupper(c); break;
case 'w'.charCodeAt(0) : res = isalnum(c); break;
case 'x'.charCodeAt(0) : res = isxdigit(c); break;
case 'z'.charCodeAt(0) : res = (c === 0); break; /* deprecated option */
default: return (cl === c);
}
return (islower(cl) ? res : !res);
};
const matchbracketclass = function(ms, c, p, ec) {
let sig = true;
if (ms.p[p + 1] === '^'.charCodeAt(0)) {
sig = false;
p++; /* skip the '^' */
}
while (++p < ec) {
if (ms.p[p] === L_ESC) {
p++;
if (match_class(c, ms.p[p]))
return sig;
} else if (ms.p[p + 1] === '-'.charCodeAt(0) && p + 2 < ec) {
p += 2;
if (ms.p[p - 2] <= c && c <= ms.p[p])
return sig;
} else if (ms.p[p] === c) return sig;
}
return !sig;
};
const singlematch = function(ms, s, p, ep) {
if (s >= ms.src_end)
return false;
else {
let c = ms.src[s];
switch (ms.p[p]) {
case '.'.charCodeAt(0): return true; /* matches any char */
case L_ESC: return match_class(c, ms.p[p + 1]);
case '['.charCodeAt(0): return matchbracketclass(ms, c, p, ep - 1);
default: return ms.p[p] === c;
}
}
};
const matchbalance = function(ms, s, p) {
if (p >= ms.p_end - 1)
lauxlib.luaL_error(ms.L, lua.to_luastring("malformed pattern (missing arguments to '%%b'"));
if (ms.src[s] !== ms.p[p])
return null;
else {
let b = ms.p[p];
let e = ms.p[p + 1];
let cont = 1;
while (++s < ms.src_end) {
if (ms.src[s] === e) {
if (--cont === 0) return s + 1;
}
else if (ms.src[s] === b) cont++;
}
}
return null; /* string ends out of balance */
};
const max_expand = function(ms, s, p, ep) {
let i = 0; /* counts maximum expand for item */
while (singlematch(ms, s + i, p, ep))
i++;
/* keeps trying to match with the maximum repetitions */
while (i >= 0) {
let res = match(ms, s + i, ep + 1);
if (res) return res;
i--; /* else didn't match; reduce 1 repetition to try again */
}
return null;
};
const min_expand = function(ms, s, p, ep) {
for (;;) {
let res = match(ms, s, ep + 1);
if (res !== null)
return res;
else if (singlematch(ms, s, p, ep))
s++; /* try with one more repetition */
else return null;
}
};
const start_capture = function(ms, s, p, what) {
let level = ms.level;
if (level >= LUA_MAXCAPTURES) lauxlib.luaL_error(ms.L, lua.to_luastring("too many captures", true));
ms.capture[level] = ms.capture[level] ? ms.capture[level] : {};
ms.capture[level].init = s;
ms.capture[level].len = what;
ms.level = level + 1;
let res;
if ((res = match(ms, s, p)) === null) /* match failed? */
ms.level--; /* undo capture */
return res;
};
const end_capture = function(ms, s, p) {
let l = capture_to_close(ms);
ms.capture[l].len = s - ms.capture[l].init; /* close capture */
let res;
if ((res = match(ms, s, p)) === null) /* match failed? */
ms.capture[l].len = CAP_UNFINISHED; /* undo capture */
return res;
};
/* Compare the elements of arrays 'a' and 'b' to see if they contain the same elements */
const array_cmp = function(a, ai, b, bi, len) {
let aj = ai+len;
for (; ai < aj; ai++, bi++) {
if (a[ai] !== b[bi])
return false;
}
return true;
};
const match_capture = function(ms, s, l) {
l = check_capture(ms, l);
let len = ms.capture[l].len;
if ((ms.src_end-s) >= len && array_cmp(ms.src, ms.capture[l].init, ms.src, s, len))
return s+len;
else return null;
};
const match = function(ms, s, p) {
let gotodefault = false;
let gotoinit = true;
if (ms.matchdepth-- === 0)
lauxlib.luaL_error(ms.L, lua.to_luastring("pattern too complex", true));
while (gotoinit || gotodefault) {
gotoinit = false;
if (p !== ms.p_end) { /* end of pattern? */
switch (gotodefault ? 'x'.charCodeAt(0) : ms.p[p]) {
case '('.charCodeAt(0): { /* start capture */
if (ms.p[p + 1] === ')'.charCodeAt(0)) /* position capture? */
s = start_capture(ms, s, p + 2, CAP_POSITION);
else
s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
break;
}
case ')'.charCodeAt(0): { /* end capture */
s = end_capture(ms, s, p + 1);
break;
}
case '$'.charCodeAt(0): {
if (p + 1 !== ms.p_end) { /* is the '$' the last char in pattern? */
gotodefault = true; /* no; go to default */
break;
}
s = ms.src.slice(s).length === 0 ? s : null; /* check end of string */
break;
}
case L_ESC: { /* escaped sequences not in the format class[*+?-]? */
switch (ms.p[p + 1]) {
case 'b'.charCodeAt(0): { /* balanced string? */
s = matchbalance(ms, s, p + 2);
if (s !== null) {
p += 4;
gotoinit = true;
}
break;
}
case 'f'.charCodeAt(0): { /* frontier? */
p += 2;
if (ms.p[p] !== '['.charCodeAt(0))
lauxlib.luaL_error(ms.L, lua.to_luastring("missing '[' after '%%f' in pattern"));
let ep = classend(ms, p); /* points to what is next */
let previous = s === ms.src_init ? 0 : ms.src[s-1];
if (!matchbracketclass(ms, previous, p, ep - 1) && matchbracketclass(ms, (s===ms.src_end)?0:ms.src[s], p, ep - 1)) {
p = ep; gotoinit = true; break;
}
s = null; /* match failed */
break;
}
case '0'.charCodeAt(0): case '1'.charCodeAt(0): case '2'.charCodeAt(0): case '3'.charCodeAt(0):
case '4'.charCodeAt(0): case '5'.charCodeAt(0): case '6'.charCodeAt(0): case '7'.charCodeAt(0):
case '8'.charCodeAt(0): case '9'.charCodeAt(0): { /* capture results (%0-%9)? */
s = match_capture(ms, s, ms.p[p + 1]);
if (s !== null) {
p += 2; gotoinit = true;
}
break;
}
default: gotodefault = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment