“初始化俯视角工程,带puerts,未编过”

This commit is contained in:
2024-12-01 02:11:25 +08:00
parent 04698dd585
commit 850d76173c
1491 changed files with 271579 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may be subject to their corresponding license terms.
* This file is subject to the terms and conditions defined in file 'LICENSE', which is part of this source code package.
*/
const ffi_bindings = require('ffi_bindings');
const typeInfo = require('type').typeInfo;
const pointer = typeInfo('pointer');
const ffi_call = ffi_bindings.ffi_call;
const UTF8Length = ffi_bindings.UTF8Length;
const writeUTF8String = ffi_bindings.writeUTF8String;
const readUTF8String = ffi_bindings.readUTF8String;
function stringToCString(str) {
let buffLen = UTF8Length(str);
let buff = new Uint8Array(buffLen + 1);
writeUTF8String(buff, str);
return buff;
}
function id(x) {
return x;
}
function allocCif(returnType, parameterTypes, abi, fixArgNum) {
let param_ffi_types = parameterTypes.map(t => t.ffi_type);
let cifPtr = new Uint8Array(ffi_bindings.FFI_CIF_SIZE);
let status
if (typeof fixArgNum === 'number') {
status = ffi_bindings.ffi_prep_cif_var(cifPtr, abi, fixArgNum, parameterTypes.length, returnType.ffi_type, pointer.alloc(...param_ffi_types));
} else {
status = ffi_bindings.ffi_prep_cif(cifPtr, abi, parameterTypes.length, returnType.ffi_type, pointer.alloc(...param_ffi_types));
}
if (status != 0) {
throw new Error(`call ffi_prep_cif fail, status=${status}`);
}
return cifPtr;
}
function binding(func, abi, returnType, parameterTypes, fixArgNum) {
if (typeof abi !== 'number') {
fixArgNum = parameterTypes;
parameterTypes = returnType;
returnType = abi;
abi = ffi_bindings.FFI_DEFAULT_ABI;
}
const argsProcessers = parameterTypes.map(t => t === 'cstring' ? stringToCString : id);
const resultProcesser = returnType === 'cstring' ? readUTF8String : id;
returnType = typeInfo(returnType);
parameterTypes = parameterTypes.map(t => typeInfo(t));
const cifPtr = allocCif(returnType, parameterTypes, abi, fixArgNum);
let argPtrs = parameterTypes.map(t => t.alloc());
let retPtr = returnType.alloc();
const ffi_call_args = pointer.alloc(...argPtrs);
const expectArgNum = parameterTypes.length;
function wrap(...args) {
if (args.length != expectArgNum) {
throw new Error(`expect ${expectArgNum} argument but got ${args.length}`);
}
for (var i = 0; i < expectArgNum; i++) {
args[i] = argsProcessers[i](args[i]);
parameterTypes[i].write(argPtrs[i], args[i]);
}
ffi_call(cifPtr, func, retPtr, ffi_call_args);
return resultProcesser(returnType.read(retPtr));
}
return wrap;
}
function allocClosure(func, abi, returnType, parameterTypes) {
if (typeof abi !== 'number') {
parameterTypes = returnType;
returnType = abi;
abi = ffi_bindings.FFI_DEFAULT_ABI;
}
returnType = typeInfo(returnType);
parameterTypes = parameterTypes.map(t => typeInfo(t));
const cifPtr = allocCif(returnType, parameterTypes, abi);
return ffi_bindings.ffi_alloc_closure(cifPtr, function(retPtr, argPtrs) {
try {
var args = [];
for (var i = 0; i < parameterTypes.length; i++) {
var argPtr = pointer.read(argPtrs, i * pointer.size, parameterTypes[i].size);
args.push(parameterTypes[i].read(argPtr));
}
var result = func.apply(null, args);
returnType.write(retPtr, result);
} catch (e) {
console.error('js callback exception, msg=', e);
}
}, returnType.size);
}
function nativeFunctionPtr(cl) {
return pointer.read(cl);
}
function freeClosure(cl) {
ffi_bindings.ffi_free_closure(cl);
}
exports.binding = binding;
exports.closure = {
alloc: allocClosure,
func: nativeFunctionPtr,
free: freeClosure
}
+342
View File
@@ -0,0 +1,342 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may be subject to their corresponding license terms.
* This file is subject to the terms and conditions defined in file 'LICENSE', which is part of this source code package.
*/
function validateNumber(value, type) {
if (typeof value !== 'number')
throw new Error(type + " expect an number but got " + value);
}
function boundsError(value, length, type) {
if (Math.floor(value) !== value) {
validateNumber(value, type);
throw new Error((type || 'offset') + ' expect an integer but got ' + value);
}
if (length < 0)
throw new Error("out of bound");
throw new Error(type || 'offset' +
`expect >= ${type ? 1 : 0} and <= ${length} but got` + value);
}
function checkBounds(buf, offset, byteLength) {
validateNumber(offset, 'offset');
if (buf[offset] === undefined || buf[offset + byteLength] === undefined)
boundsError(offset, buf.length - (byteLength + 1));
}
function writeU_Int8(buf, value, offset, min, max) {
value = +value;
// `checkInt()` can not be used here because it checks two entries.
validateNumber(offset, 'offset');
if (value > max || value < min) {
throw new Error(`value expect >= ${min} and <= ${max} but got ` + value);
}
if (buf[offset] === undefined)
boundsError(offset, buf.length - 1);
buf[offset] = value;
return offset + 1;
}
function readInt8(buff, offset = 0) {
validateNumber(offset, 'offset');
const val = buff[offset];
if (val === undefined)
boundsError(offset, buff.length - 1);
return val | (val & 2 ** 7) * 0x1fffffe;
}
function writeInt8(buf, value, offset = 0) {
return writeU_Int8(buf, value, offset, -0x80, 0x7f);
}
function readUInt8(offset = 0) {
validateNumber(offset, 'offset');
const val = this[offset];
if (val === undefined)
boundsError(offset, this.length - 1);
return val;
}
function writeUInt8(value, offset = 0) {
return writeU_Int8(this, value, offset, 0, 0xff);
}
const int16Array = new Int16Array(1);
const uInt8Int6Array = new Uint8Array(int16Array.buffer);
function readInt16(buff, offset = 0) {
validateNumber(offset, 'offset');
const first = buff[offset];
const last = buff[offset + 1];
if (first === undefined || last === undefined)
boundsError(offset, buff.length - 2);
uInt8Int6Array[0] = first;
uInt8Int6Array[1] = last;
return int16Array[0];
}
function writeInt16(buff, val, offset = 0) {
val = +val;
checkBounds(buff, offset, 1);
int16Array[0] = val;
buff[offset++] = uInt8Int6Array[0];
buff[offset++] = uInt8Int6Array[1];
return offset;
}
const uint16Array = new Uint16Array(1);
const uint8Uint16Array = new Uint8Array(uint16Array.buffer);
function readUInt16(buff, offset = 0) {
validateNumber(offset, 'offset');
const first = buff[offset];
const last = buff[offset + 1];
if (first === undefined || last === undefined)
boundsError(offset, buff.length - 2);
uint8Uint16Array[0] = first;
uint8Uint16Array[1] = last;
return uint16Array[0];
}
function writeUInt16(buff, val, offset = 0) {
val = +val;
checkBounds(buff, offset, 1);
uint16Array[0] = val;
buff[offset++] = uint8Uint16Array[0];
buff[offset++] = uint8Uint16Array[1];
return offset;
}
const int32Array = new Int32Array(1);
const uint8Int32Array = new Uint8Array(int32Array.buffer);
function readInt32(buff, offset = 0) {
validateNumber(offset, 'offset');
const first = buff[offset];
const last = buff[offset + 3];
if (first === undefined || last === undefined)
boundsError(offset, buff.length - 4);
uint8Int32Array[0] = first;
uint8Int32Array[1] = buff[++offset];
uint8Int32Array[2] = buff[++offset];
uint8Int32Array[3] = last;
return int32Array[0];
}
function writeInt32(buff, val, offset = 0) {
val = +val;
checkBounds(buff, offset, 3);
int32Array[0] = val;
buff[offset++] = uint8Int32Array[0];
buff[offset++] = uint8Int32Array[1];
buff[offset++] = uint8Int32Array[2];
buff[offset++] = uint8Int32Array[3];
return offset;
}
const uint32Array = new Uint32Array(1);
const uint8Uint32Array = new Uint8Array(uint32Array.buffer);
function readUInt32(buff, offset = 0) {
validateNumber(offset, 'offset');
const first = buff[offset];
const last = buff[offset + 3];
if (first === undefined || last === undefined)
boundsError(offset, buff.length - 4);
uint8Uint32Array[0] = first;
uint8Uint32Array[1] = buff[++offset];
uint8Uint32Array[2] = buff[++offset];
uint8Uint32Array[3] = last;
return uint32Array[0];
}
function writeUInt32(buff, val, offset = 0) {
val = +val;
checkBounds(buff, offset, 3);
uint32Array[0] = val;
buff[offset++] = uint8Uint32Array[0];
buff[offset++] = uint8Uint32Array[1];
buff[offset++] = uint8Uint32Array[2];
buff[offset++] = uint8Uint32Array[3];
return offset;
}
const float32Array = new Float32Array(1);
const uInt8Float32Array = new Uint8Array(float32Array.buffer);
function readFloat(buff, offset = 0) {
validateNumber(offset, 'offset');
const first = buff[offset];
const last = buff[offset + 3];
if (first === undefined || last === undefined)
boundsError(offset, buff.length - 4);
uInt8Float32Array[0] = first;
uInt8Float32Array[1] = buff[++offset];
uInt8Float32Array[2] = buff[++offset];
uInt8Float32Array[3] = last;
return float32Array[0];
}
function writeFloat(buff, val, offset = 0) {
val = +val;
checkBounds(buff, offset, 3);
float32Array[0] = val;
buff[offset++] = uInt8Float32Array[0];
buff[offset++] = uInt8Float32Array[1];
buff[offset++] = uInt8Float32Array[2];
buff[offset++] = uInt8Float32Array[3];
return offset;
}
const float64Array = new Float64Array(1);
const uInt8Float64Array = new Uint8Array(float64Array.buffer);
function readDouble(buff, offset = 0) {
const first = buff[offset];
const last = buff[offset + 7];
if (first === undefined || last === undefined)
boundsError(offset, buff.length - 8);
uInt8Float64Array[0] = first;
uInt8Float64Array[1] = buff[++offset];
uInt8Float64Array[2] = buff[++offset];
uInt8Float64Array[3] = buff[++offset];
uInt8Float64Array[4] = buff[++offset];
uInt8Float64Array[5] = buff[++offset];
uInt8Float64Array[6] = buff[++offset];
uInt8Float64Array[7] = last;
return float64Array[0];
}
function writeDouble(buff, val, offset = 0) {
val = +val;
checkBounds(buff, offset, 7);
float64Array[0] = val;
buff[offset++] = uInt8Float64Array[0];
buff[offset++] = uInt8Float64Array[1];
buff[offset++] = uInt8Float64Array[2];
buff[offset++] = uInt8Float64Array[3];
buff[offset++] = uInt8Float64Array[4];
buff[offset++] = uInt8Float64Array[5];
buff[offset++] = uInt8Float64Array[6];
buff[offset++] = uInt8Float64Array[7];
return offset;
}
const bigInt64Array = new BigInt64Array(1);
const uint8BigInt64Array = new Uint8Array(bigInt64Array.buffer);
function readInt64(buff, offset = 0) {
const first = buff[offset];
const last = buff[offset + 7];
if (first === undefined || last === undefined)
boundsError(offset, buff.length - 8);
uint8BigInt64Array[0] = first;
uint8BigInt64Array[1] = buff[++offset];
uint8BigInt64Array[2] = buff[++offset];
uint8BigInt64Array[3] = buff[++offset];
uint8BigInt64Array[4] = buff[++offset];
uint8BigInt64Array[5] = buff[++offset];
uint8BigInt64Array[6] = buff[++offset];
uint8BigInt64Array[7] = last;
return bigInt64Array[0];
}
function writeInt64(buff, val, offset = 0) {
val = +val;
if (typeof val === 'number') val = BigInt(val);
checkBounds(buff, offset, 7);
bigInt64Array[0] = val;
buff[offset++] = uint8BigInt64Array[0];
buff[offset++] = uint8BigInt64Array[1];
buff[offset++] = uint8BigInt64Array[2];
buff[offset++] = uint8BigInt64Array[3];
buff[offset++] = uint8BigInt64Array[4];
buff[offset++] = uint8BigInt64Array[5];
buff[offset++] = uint8BigInt64Array[6];
buff[offset++] = uint8BigInt64Array[7];
return offset;
}
const bigUint64Array = new BigUint64Array(1);
const uint8BigUint64Array = new Uint8Array(bigUint64Array.buffer);
function readUInt64(buff, offset = 0) {
const first = buff[offset];
const last = buff[offset + 7];
if (first === undefined || last === undefined)
boundsError(offset, buff.length - 8);
uint8BigUint64Array[0] = first;
uint8BigUint64Array[1] = buff[++offset];
uint8BigUint64Array[2] = buff[++offset];
uint8BigUint64Array[3] = buff[++offset];
uint8BigUint64Array[4] = buff[++offset];
uint8BigUint64Array[5] = buff[++offset];
uint8BigUint64Array[6] = buff[++offset];
uint8BigUint64Array[7] = last;
return bigUint64Array[0];
}
function writeUInt64(buff, val, offset = 0) {
val = +val;
if (typeof val === 'number') val = BigInt(val);
checkBounds(buff, offset, 7);
bigUint64Array[0] = val;
buff[offset++] = uint8BigUint64Array[0];
buff[offset++] = uint8BigUint64Array[1];
buff[offset++] = uint8BigUint64Array[2];
buff[offset++] = uint8BigUint64Array[3];
buff[offset++] = uint8BigUint64Array[4];
buff[offset++] = uint8BigUint64Array[5];
buff[offset++] = uint8BigUint64Array[6];
buff[offset++] = uint8BigUint64Array[7];
return offset;
}
let ffi_bindings = require('ffi_bindings');
ffi_bindings.readInt8 = readInt8;
ffi_bindings.readUInt8 = readUInt8;
ffi_bindings.readInt16 = readInt16;
ffi_bindings.readUInt16 = readUInt16;
ffi_bindings.readInt32 = readInt32;
ffi_bindings.readUInt32 = readUInt32;
ffi_bindings.readInt64 = readInt64;
ffi_bindings.readUInt64 = readUInt64;
ffi_bindings.readFloat = readFloat;
ffi_bindings.readDouble = readDouble;
ffi_bindings.writeInt8 = writeInt8;
ffi_bindings.writeUInt8 = writeUInt8;
ffi_bindings.writeInt16 = writeInt16;
ffi_bindings.writeUInt16 = writeUInt16;
ffi_bindings.writeInt32 = writeInt32;
ffi_bindings.writeUInt32 = writeUInt32;
ffi_bindings.writeInt64 = writeInt64;
ffi_bindings.writeUInt64 = writeUInt64;
ffi_bindings.writeFloat = writeFloat;
ffi_bindings.writeDouble = writeDouble;
+13
View File
@@ -0,0 +1,13 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may be subject to their corresponding license terms.
* This file is subject to the terms and conditions defined in file 'LICENSE', which is part of this source code package.
*/
module.exports = require('ffi_bindings');
module.exports.binding = require('binding').binding;
module.exports.closure= require('binding').closure;
module.exports.typeInfo = require('type').typeInfo;
module.exports.makeStruct = require('type').makeStruct;
module.exports.makePointer = require('type').makePointer;
+210
View File
@@ -0,0 +1,210 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may be subject to their corresponding license terms.
* This file is subject to the terms and conditions defined in file 'LICENSE', which is part of this source code package.
*/
let ffi_bindings = require('ffi_bindings');
require('buffer-ext.js');
let primitiveTypes = Object.create(null);
Object.keys(ffi_bindings.sizeof).forEach(function (name) {
let uname;
if (name.startsWith("ui")) {
uname = name.slice(0, 2).toUpperCase() + name.slice(2);
} else {
uname = name.charAt(0).toUpperCase() + name.slice(1);
}
primitiveTypes[name] = {
ffi_type: ffi_bindings.FFI_TYPES[name],
size: ffi_bindings.sizeof[name],
align: ffi_bindings.alignof[name],
write: ffi_bindings["write" + uname],
read: ffi_bindings["read" + uname],
set: set,
get: get,
alloc: alloc
}
});
primitiveTypes.cstring = primitiveTypes.pointer;
function doNothing(){}
primitiveTypes["void"] = {
ffi_type: ffi_bindings.FFI_TYPES['void'],
size: 0,
align: 0,
write: doNothing,
read: doNothing,
set: doNothing,
get: doNothing,
alloc: doNothing
}
function typeInfo(t) {
return (typeof t === 'string') ? primitiveTypes[t] : t;
}
const pointer = primitiveTypes.pointer;
const sizeType = pointer.size == 4 ? "uint32" : "uint64";
primitiveTypes.size_t = {
ffi_type: pointer.ffi_type,
size: pointer.size,
align: pointer.align,
write: primitiveTypes[sizeType].write,
read: primitiveTypes[sizeType].read,
set: set,
get: get,
alloc: alloc
}
function makePointer(t) {
t = typeInfo(t);
let ret = Object.assign({}, pointer);
const orgRead = ret.read;
function readTypedPointer(buffer, offset) {
return orgRead(buffer, offset, t.size);
}
function ref(value) {
return t.alloc(value);
}
function unref(buff) {
return t.read(buff);
}
ret.read = readTypedPointer;
ret.ref = ref;
ret.unref = unref;
return ret;
}
function makeStruct(info, noFfiType) {
function structType (buff, data) {
if (!(this instanceof structType)) {
return new structType(buff, data);
}
if (!(buff instanceof Uint8Array)) {
data = buff;
buff = new Uint8Array(structType.size);
}
this._buff = buff;
if (data) {
for (var key in data) {
this[key] = data[key];
}
}
}
function propertyDesc(name, type, offset) {
return {
enumerable: true,
configurable: true,
get: function() {
return type.read(this._buff, offset);
},
set: function(value) {
type.write(this._buff, value, offset);
}
};
}
let structSize = 0;
let structAlign = 0;
let elem_ffi_types = [];
Object.keys(info).forEach(function (name) {
fieldType = typeInfo(info[name]);
const align = fieldType.align;
const padding = (align - (structSize % align)) % align;
const desc = propertyDesc(name, fieldType, structSize + padding);
Object.defineProperty(structType.prototype, name, desc);
structSize += (padding + fieldType.size);
structAlign = Math.max(structAlign, align);
elem_ffi_types.push(fieldType.ffi_type);
});
var left = structSize % structAlign;
if (left > 0) {
structSize += structAlign - left;
}
structType.size = structSize;
structType.align = structAlign;
structType.read = structRead;
structType.write = structWrite;
structType.set = set;
structType.get = get;
structType.alloc = alloc;
if (!noFfiType) {
let ffi_type = new FFI_TYPE();
ffi_type.size = 0;
ffi_type.alignment = 0;
ffi_type.type = ffi_bindings.FFI_TYPE_STRUCT;
let elements = pointer.alloc(...elem_ffi_types, null);
ffi_type.elements = elements;
structType._elems_array = elements;//prevent gc;
structType.ffi_type = ffi_type._buff;
}
return structType;
}
var FFI_TYPE = makeStruct({
size: 'size_t',
alignment: 'uint16',
type: 'uint16',
elements: 'pointer'
}, true);
function structRead(buffer, offset) {
if (typeof offset === 'number' && offset > 0) {
buffer = new Uint8Array(buffer.buffer, offset);
}
return new this(buffer);
}
function structWrite(buffer, value, offset) {
if (value instanceof this) {
let src = value._buff;
if (typeof offset !== 'number') offset = 0;
for(var i = 0; i < this.size; i++) {
buffer[offset++] = src[i];
}
} else {
if (typeof offset === 'number' && offset > 0) {
buffer = new Uint8Array(buffer.buffer, offset);
}
new this(buffer, value);
}
}
function set(buff, val, index) {
this.write(buff, val, index * this.size);
}
function get(buff, index) {
return this.read(buff, index * this.size);
}
function alloc(...values) {
if (values.length == 0) return new Uint8Array(this.size);
let buff = new Uint8Array(values.length * this.size);
for(var i = 0; i < values.length; i++) {
this.set(buff, values[i], i);
}
return buff;
}
exports.typeInfo = typeInfo;
exports.makeStruct = makeStruct;
exports.makePointer = makePointer;