diff options
author | Chad Austin <chad@imvu.com> | 2013-04-16 17:53:38 -0700 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2013-04-18 20:08:18 +0300 |
commit | e5c04828c4c2eaec83cf25b83067064db2270c2e (patch) | |
tree | 5cffdf75236d2bb98674ace9c4c4bdb4226dff4c | |
parent | 775f840e378eba5a9a8053857113a40efb980fb7 (diff) |
fix readLatin1String to actually cover the range of latin-1 characters and add support for interned string symbols to emscripten::val
-rwxr-xr-x | src/embind/embind.js | 28 | ||||
-rwxr-xr-x | src/embind/emval.js | 27 | ||||
-rw-r--r-- | system/include/emscripten/val.h | 21 | ||||
-rw-r--r-- | tests/embind/embind_test.cpp | 4 |
4 files changed, 59 insertions, 21 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index 440fa267..753d40a4 100755 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -223,21 +223,21 @@ function whenDependentTypesAreResolved(myTypes, dependentTypes, getTypeConverter } } -var __charCodes = []; +var __charCodes = (function() { + var codes = new Array(256); + for (var i = 0; i < 256; ++i) { + codes[i] = String.fromCharCode(i); + } + return codes; +})(); function readLatin1String(ptr) { - if (__charCodes.length === 0) { - for (var charCodeI = 0; charCodeI < 127; charCodeI++) { - __charCodes.push(String.fromCharCode(charCodeI)); + var ret = ""; + var c = ptr; + while (HEAPU8[c]) { + ret += __charCodes[HEAPU8[c++]]; } - } - - var ret = ""; - var c = ptr; - while (HEAPU8[c]) { - ret += __charCodes[HEAPU8[c++]]; - } - return ret; + return ret; } function getTypeName(type) { @@ -1143,8 +1143,8 @@ function __embind_register_class_function( var humanName = classType.name + '.' + methodName; var unboundTypesHandler = function() { - throwUnboundTypeError('Cannot call ' + humanName + ' due to unbound types', rawArgTypes); - }; + throwUnboundTypeError('Cannot call ' + humanName + ' due to unbound types', rawArgTypes); + }; var proto = classType.registeredClass.instancePrototype; var method = proto[methodName]; diff --git a/src/embind/emval.js b/src/embind/emval.js index 68b613f3..c02ffa92 100755 --- a/src/embind/emval.js +++ b/src/embind/emval.js @@ -31,6 +31,21 @@ Module.get_first_emval = function() { // Private C++ API +var _emval_symbols = {}; // address -> string + +function __emval_register_symbol(address) { + _emval_symbols[address] = readLatin1String(address); +} + +function getStringOrSymbol(address) { + var symbol = _emval_symbols[address]; + if (symbol === undefined) { + return readLatin1String(address); + } else { + return symbol; + } +} + function requireHandle(handle) { if (!handle) { throwBindingError('Cannot use deleted val. handle = ' + handle); @@ -82,7 +97,7 @@ function __emval_null() { } function __emval_new_cstring(v) { - return __emval_register(readLatin1String(v)); + return __emval_register(getStringOrSymbol(v)); } function __emval_take_value(type, v) { @@ -137,12 +152,12 @@ function __emval_new(handle, argCount, argTypes) { var global = (function(){return Function;})()('return this')(); function __emval_get_global(name) { - name = readLatin1String(name); + name = getStringOrSymbol(name); return __emval_register(global[name]); } function __emval_get_module_property(name) { - name = readLatin1String(name); + name = getStringOrSymbol(name); return __emval_register(Module[name]); } @@ -188,7 +203,7 @@ function __emval_call(handle, argCount, argTypes) { function __emval_call_method(handle, name, argCount, argTypes) { requireHandle(handle); - name = readLatin1String(name); + name = getStringOrSymbol(name); var args = parseParameters( argCount, @@ -201,7 +216,7 @@ function __emval_call_method(handle, name, argCount, argTypes) { function __emval_call_void_method(handle, name, argCount, argTypes) { requireHandle(handle); - name = readLatin1String(name); + name = getStringOrSymbol(name); var args = parseParameters( argCount, @@ -212,6 +227,6 @@ function __emval_call_void_method(handle, name, argCount, argTypes) { } function __emval_has_function(handle, name) { - name = readLatin1String(name); + name = getStringOrSymbol(name); return _emval_handle_array[handle].value[name] instanceof Function; } diff --git a/system/include/emscripten/val.h b/system/include/emscripten/val.h index 1fccd434..42d8d375 100644 --- a/system/include/emscripten/val.h +++ b/system/include/emscripten/val.h @@ -8,6 +8,8 @@ namespace emscripten { namespace internal { // Implemented in JavaScript. Don't call these directly. extern "C" { + void _emval_register_symbol(const char*); + typedef struct _EM_VAL* EM_VAL; void _emval_incref(EM_VAL value); @@ -54,6 +56,25 @@ namespace emscripten { } } + class symbol { + public: + symbol() = delete; + + // I so wish I could require the argument to be a string literal + symbol(const char* address) + : address(address) + { + internal::_emval_register_symbol(address); + } + + operator const char*() const { + return address; + } + + private: + const char* address; + }; + class val { public: // missing operators: diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp index 5733c08f..9bab2872 100644 --- a/tests/embind/embind_test.cpp +++ b/tests/embind/embind_test.cpp @@ -1087,6 +1087,8 @@ public: }
};
+symbol optionalMethodSymbol = "optionalMethod";
+
class AbstractClassWrapper : public wrapper<AbstractClass> {
public:
EMSCRIPTEN_WRAPPER(AbstractClassWrapper);
@@ -1095,7 +1097,7 @@ public: return call<std::string>("abstractMethod");
}
std::string optionalMethod(std::string s) const {
- return optional_call<std::string>("optionalMethod", [&] {
+ return optional_call<std::string>(optionalMethodSymbol, [&] {
return AbstractClass::optionalMethod(s);
}, s);
}
|