aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@imvu.com>2013-04-16 17:53:38 -0700
committerJukka Jylänki <jujjyl@gmail.com>2013-04-18 20:08:18 +0300
commite5c04828c4c2eaec83cf25b83067064db2270c2e (patch)
tree5cffdf75236d2bb98674ace9c4c4bdb4226dff4c
parent775f840e378eba5a9a8053857113a40efb980fb7 (diff)
fix readLatin1String to actually cover the range of latin-1 characters and add support for interned string symbols to emscripten::val
-rwxr-xr-xsrc/embind/embind.js28
-rwxr-xr-xsrc/embind/emval.js27
-rw-r--r--system/include/emscripten/val.h21
-rw-r--r--tests/embind/embind_test.cpp4
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);
}