Convert embind/emval to JS library format.

This commit is contained in:
Bruce Mitchener 2014-05-29 08:01:22 +07:00
Родитель 03fa2a59c1
Коммит 350f199fb9
4 изменённых файлов: 565 добавлений и 351 удалений

13
emcc
Просмотреть файл

@ -959,6 +959,8 @@ try:
elif newargs[i] == '--bind':
bind = True
newargs[i] = ''
js_libraries.append(shared.path_from_root('src', 'embind', 'emval.js'))
js_libraries.append(shared.path_from_root('src', 'embind', 'embind.js'))
if default_cxx_std:
default_cxx_std = '-std=c++11' # Force C++11 for embind code, but only if user has not explicitly overridden a standard.
elif newargs[i].startswith('-std='):
@ -1675,17 +1677,6 @@ try:
open(final, 'w').write(pre_js + src + post_js)
if DEBUG: save_intermediate('pre-post')
# Add bindings glue if used
if bind:
logging.debug('adding embind glue')
src = open(final).read().replace('// {{PRE_RUN_ADDITIONS}}', '// {{PRE_RUN_ADDITIONS}}\n' +
open(shared.path_from_root('src', 'embind', 'embind.js')).read() +
open(shared.path_from_root('src', 'embind', 'emval.js')).read()
)
final += '.bd.js'
open(final, 'w').write(src)
if DEBUG: save_intermediate('bind')
# Apply a source code transformation, if requested
if js_transform:
shutil.copyfile(final, final + '.tr.js')

Просмотреть файл

@ -83,14 +83,9 @@ def emscripten(env, target_js, source_bc):
buildName('raw.js'),
[opt_ll])
prejs = [
env['EMSCRIPTEN_PREJS'],
'${EMSCRIPTEN_HOME}/src/embind/emval.js',
'${EMSCRIPTEN_HOME}/src/embind/embind.js' ]
[concatenated_js] = env.Concatenate(
buildName('concat.js'),
[ prejs,
[ env['EMSCRIPTEN_PREJS'],
raw_emscripten_js,
env['EMSCRIPTEN_POSTJS'] ])
@ -111,7 +106,7 @@ def emscripten(env, target_js, source_bc):
[iter_global_emscripten_js] = env.Concatenate(
buildName('iter.js'),
[ prejs,
[ env['EMSCRIPTEN_PREJS'],
raw_emscripten_js,
env['EMSCRIPTEN_POSTJS'] ])

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -6,116 +6,134 @@
/*global requireRegisteredType, throwBindingError, runDestructors*/
/*jslint sub:true*/ /* The symbols 'fromWireType' and 'toWireType' must be accessed via array notation to be closure-safe since craftInvokerFunction crafts functions as strings that can't be closured. */
var Module = Module || {};
// -- jshint doesn't understand library syntax, so we need to mark the symbols exposed here
/*global getStringOrSymbol, emval_handle_array, __emval_register, __emval_unregister, requireHandle, count_emval_handles, emval_symbols, emval_free_list, get_first_emval, __emval_decref, emval_newers*/
/*global craftEmvalAllocator, __emval_addMethodCaller, emval_methodCallers, LibraryManager, mergeInto, __emval_allocateDestructors, global, __emval_lookupTypes, makeLegalFunctionName*/
/*global emval_get_global*/
var _emval_handle_array = [{}]; // reserve zero
var _emval_free_list = [];
var LibraryEmVal = {
$emval_handle_array: [{}], // reserve zero
$emval_free_list: [],
$emval_symbols: {}, // address -> string
// Public JS API
$init_emval__deps: ['$count_emval_handles', '$get_first_emval'],
$init_emval__postset: 'init_emval();',
$init_emval: function() {
Module['count_emval_handles'] = count_emval_handles;
Module['get_first_emval'] = get_first_emval;
},
/** @expose */
Module.count_emval_handles = function() {
$count_emval_handles__deps: ['$emval_handle_array'],
$count_emval_handles: function() {
var count = 0;
for (var i = 1; i < _emval_handle_array.length; ++i) {
if (_emval_handle_array[i] !== undefined) {
for (var i = 1; i < emval_handle_array.length; ++i) {
if (emval_handle_array[i] !== undefined) {
++count;
}
}
return count;
};
},
/** @expose */
Module.get_first_emval = function() {
for (var i = 1; i < _emval_handle_array.length; ++i) {
if (_emval_handle_array[i] !== undefined) {
return _emval_handle_array[i];
$get_first_emval__deps: ['$emval_handle_array'],
$get_first_emval: function() {
for (var i = 1; i < emval_handle_array.length; ++i) {
if (emval_handle_array[i] !== undefined) {
return emval_handle_array[i];
}
}
return null;
};
},
// Private C++ API
_emval_register_symbol__deps: ['$emval_symbols', '$readLatin1String'],
_emval_register_symbol: function(address) {
emval_symbols[address] = readLatin1String(address);
},
var _emval_symbols = {}; // address -> string
function __emval_register_symbol(address) {
_emval_symbols[address] = readLatin1String(address);
}
function getStringOrSymbol(address) {
var symbol = _emval_symbols[address];
$getStringOrSymbol__deps: ['$emval_symbols', '$readLatin1String'],
$getStringOrSymbol: function(address) {
var symbol = emval_symbols[address];
if (symbol === undefined) {
return readLatin1String(address);
} else {
return symbol;
}
}
},
function requireHandle(handle) {
$requireHandle__deps: ['$emval_handle_array', '$throwBindingError'],
$requireHandle: function(handle) {
if (!handle) {
throwBindingError('Cannot use deleted val. handle = ' + handle);
}
return _emval_handle_array[handle].value;
}
return emval_handle_array[handle].value;
},
function __emval_register(value) {
var handle = _emval_free_list.length ?
_emval_free_list.pop() :
_emval_handle_array.length;
_emval_register__deps: ['$emval_free_list', '$emval_handle_array', '$init_emval'],
_emval_register: function(value) {
var handle = emval_free_list.length ?
emval_free_list.pop() :
emval_handle_array.length;
_emval_handle_array[handle] = {refcount: 1, value: value};
emval_handle_array[handle] = {refcount: 1, value: value};
return handle;
}
},
function __emval_incref(handle) {
_emval_incref__deps: ['$emval_handle_array'],
_emval_incref: function(handle) {
if (handle) {
_emval_handle_array[handle].refcount += 1;
emval_handle_array[handle].refcount += 1;
}
}
},
function __emval_decref(handle) {
if (handle && 0 === --_emval_handle_array[handle].refcount) {
_emval_handle_array[handle] = undefined;
_emval_free_list.push(handle);
_emval_decref__deps: ['$emval_free_list', '$emval_handle_array'],
_emval_decref: function(handle) {
if (handle && 0 === --emval_handle_array[handle].refcount) {
emval_handle_array[handle] = undefined;
emval_free_list.push(handle);
}
}
},
function __emval_run_destructors(handle) {
var destructors = _emval_handle_array[handle].value;
_emval_run_destructors__deps: ['_emval_decref', '$emval_handle_array', '$runDestructors'],
_emval_run_destructors: function(handle) {
var destructors = emval_handle_array[handle].value;
runDestructors(destructors);
__emval_decref(handle);
}
},
function __emval_new_array() {
_emval_new_array__deps: ['_emval_register'],
_emval_new_array: function() {
return __emval_register([]);
}
},
function __emval_new_object() {
_emval_new_object__deps: ['_emval_register'],
_emval_new_object: function() {
return __emval_register({});
}
},
function __emval_undefined() {
_emval_undefined__deps: ['_emval_register'],
_emval_undefined: function() {
return __emval_register(undefined);
}
},
function __emval_null() {
_emval_null__deps: ['_emval_register'],
_emval_null: function() {
return __emval_register(null);
}
},
function __emval_new_cstring(v) {
_emval_new_cstring__deps: ['$getStringOrSymbol', '_emval_register'],
_emval_new_cstring: function(v) {
return __emval_register(getStringOrSymbol(v));
}
},
function __emval_take_value(type, argv) {
_emval_take_value__deps: ['_emval_register', '$requireRegisteredType'],
_emval_take_value: function(type, argv) {
type = requireRegisteredType(type, '_emval_take_value');
var v = type['readValueFromPointer'](argv);
return __emval_register(v);
}
},
var __newers = {}; // arity -> function
function craftEmvalAllocator(argCount) {
$emval_newers: {}, // arity -> function
$craftEmvalAllocator__deps: ['_emval_register', '$requireRegisteredType'],
$craftEmvalAllocator: function(argCount) {
/*This function returns a new function that looks like this:
function emval_allocator_3(constructor, argTypes, args) {
var argType0 = requireRegisteredType(HEAP32[(argTypes >> 2)], "parameter 0");
@ -150,58 +168,64 @@ function craftEmvalAllocator(argCount) {
/*jshint evil:true*/
return (new Function("requireRegisteredType", "HEAP32", "__emval_register", functionBody))(
requireRegisteredType, HEAP32, __emval_register);
}
},
function __emval_new(handle, argCount, argTypes, args) {
_emval_new__deps: ['$craftEmvalAllocator', '$emval_newers', '$requireHandle'],
_emval_new: function(handle, argCount, argTypes, args) {
handle = requireHandle(handle);
var newer = __newers[argCount];
var newer = emval_newers[argCount];
if (!newer) {
newer = craftEmvalAllocator(argCount);
__newers[argCount] = newer;
emval_newers[argCount] = newer;
}
return newer(handle, argTypes, args);
}
},
// appease jshint (technically this code uses eval)
var global = (function(){return Function;})()('return this')();
function __emval_get_global(name) {
// appease jshint (technically this code uses eval)
$emval_get_global: function() { return (function(){return Function;})()('return this')(); },
_emval_get_global__deps: ['_emval_register', '$getStringOrSymbol', '$emval_get_global'],
_emval_get_global: function(name) {
name = getStringOrSymbol(name);
return __emval_register(global[name]);
}
return __emval_register(emval_get_global()[name]);
},
function __emval_get_module_property(name) {
_emval_get_module_property__deps: ['$getStringOrSymbol', '_emval_register'],
_emval_get_module_property: function(name) {
name = getStringOrSymbol(name);
return __emval_register(Module[name]);
}
},
function __emval_get_property(handle, key) {
_emval_get_property__deps: ['_emval_register', '$requireHandle'],
_emval_get_property: function(handle, key) {
handle = requireHandle(handle);
key = requireHandle(key);
return __emval_register(handle[key]);
}
},
function __emval_set_property(handle, key, value) {
_emval_set_property__deps: ['$requireHandle'],
_emval_set_property: function(handle, key, value) {
handle = requireHandle(handle);
key = requireHandle(key);
value = requireHandle(value);
handle[key] = value;
}
},
function __emval_as(handle, returnType, destructorsRef) {
_emval_as__deps: ['_emval_register', '$requireHandle', '$requireRegisteredType'],
_emval_as: function(handle, returnType, destructorsRef) {
handle = requireHandle(handle);
returnType = requireRegisteredType(returnType, 'emval::as');
var destructors = [];
var rd = __emval_register(destructors);
HEAP32[destructorsRef >> 2] = rd;
return returnType['toWireType'](destructors, handle);
}
},
function __emval_call(handle, argCount, argTypes, argv) {
_emval_call__deps: ['_emval_lookupTypes', '_emval_register', '$requireHandle'],
_emval_call: function(handle, argCount, argTypes, argv) {
handle = requireHandle(handle);
var types = lookupTypes(argCount, argTypes);
var types = __emval_lookupTypes(argCount, argTypes);
var args = new Array(argCount);
for (var i = 0; i < argCount; ++i) {
@ -212,9 +236,10 @@ function __emval_call(handle, argCount, argTypes, argv) {
var rv = handle.apply(undefined, args);
return __emval_register(rv);
}
},
function lookupTypes(argCount, argTypes, argWireTypes) {
_emval_lookupTypes__deps: ['$requireRegisteredType'],
_emval_lookupTypes: function(argCount, argTypes, argWireTypes) {
var a = new Array(argCount);
for (var i = 0; i < argCount; ++i) {
a[i] = requireRegisteredType(
@ -222,26 +247,29 @@ function lookupTypes(argCount, argTypes, argWireTypes) {
"parameter " + i);
}
return a;
}
},
function allocateDestructors(destructorsRef) {
_emval_allocateDestructors__deps: ['_emval_register'],
_emval_allocateDestructors: function(destructorsRef) {
var destructors = [];
HEAP32[destructorsRef >> 2] = __emval_register(destructors);
return destructors;
}
},
// Leave id 0 undefined. It's not a big deal, but might be confusing
// to have null be a valid method caller.
var methodCallers = [undefined];
// Leave id 0 undefined. It's not a big deal, but might be confusing
// to have null be a valid method caller.
$emval_methodCallers: [undefined],
function addMethodCaller(caller) {
var id = methodCallers.length;
methodCallers.push(caller);
_emval_addMethodCaller__deps: ['$emval_methodCallers'],
_emval_addMethodCaller: function(caller) {
var id = emval_methodCallers.length;
emval_methodCallers.push(caller);
return id;
}
},
function __emval_get_method_caller(argCount, argTypes) {
var types = lookupTypes(argCount, argTypes);
_emval_get_method_caller__deps: ['_emval_addMethodCaller', '_emval_lookupTypes', '$new_'],
_emval_get_method_caller: function(argCount, argTypes) {
var types = __emval_lookupTypes(argCount, argTypes);
var retType = types[0];
var signatureName = retType.name + "_$" + types.slice(1).map(function (t) { return t.name; }).join("_") + "$";
@ -278,26 +306,32 @@ function __emval_get_method_caller(argCount, argTypes) {
params.push(functionBody);
var invokerFunction = new_(Function, params).apply(null, args);
return addMethodCaller(createNamedFunction(signatureName, invokerFunction));
}
return __emval_addMethodCaller(createNamedFunction(signatureName, invokerFunction));
},
function __emval_call_method(caller, handle, methodName, destructorsRef, args) {
caller = methodCallers[caller];
_emval_call_method__deps: ['_emval_allocateDestructors', '$getStringOrSymbol', '$emval_methodCallers', '$requireHandle'],
_emval_call_method: function(caller, handle, methodName, destructorsRef, args) {
caller = emval_methodCallers[caller];
handle = requireHandle(handle);
methodName = getStringOrSymbol(methodName);
return caller(handle, methodName, allocateDestructors(destructorsRef), args);
}
return caller(handle, methodName, __emval_allocateDestructors(destructorsRef), args);
},
function __emval_has_function(handle, name, classType) {
_emval_has_function__deps: ['$getStringOrSymbol', '$requireHandle', '$requireRegisteredType'],
_emval_has_function: function(handle, name, classType) {
handle = requireHandle(handle);
name = getStringOrSymbol(name);
classType = requireRegisteredType(classType, 'class wrapper filter');
var filter = classType.registeredClass.instancePrototype[name];
return (handle[name] instanceof Function) && (filter === undefined || handle[name] !== filter);
}
},
function __emval_typeof(handle) {
_emval_typeof__deps: ['_emval_register', '$requireHandle'],
_emval_typeof: function(handle) {
handle = requireHandle(handle);
return __emval_register(typeof handle);
}
},
};
mergeInto(LibraryManager.library, LibraryEmVal);