shithub: libmujs

Download patch

ref: f3ea55fc6440ca9bf08e472f2d5e1f14ee0f4273
parent: 32c0c6c4103e8753ac8ad8ca581bec9c87362ca0
author: Tor Andersson <[email protected]>
date: Sun Jan 19 10:06:10 EST 2014

Implement String.prototype.charAt and charCodeAt.

--- a/jsbstring.c
+++ b/jsbstring.c
@@ -32,6 +32,54 @@
 	return 1;
 }
 
+static inline const char *utfindex(const char *s, int i)
+{
+	Rune rune;
+	int c, n = 0;
+	for (n = 0; n < i; ++n) {
+		c = *(unsigned char*)s;
+		if (c < Runeself) {
+			if (c == 0)
+				return NULL;
+			++s;
+		} else
+			s += chartorune(&rune, s);
+	}
+	return s;
+}
+
+static int Sp_charAt(js_State *J, int n)
+{
+	char buf[UTFmax + 1];
+	const char *s = js_tostring(J, 0);
+	int pos = js_tointeger(J, 1);
+	s = utfindex(s, pos);
+	if (s) {
+		Rune rune;
+		chartorune(&rune, s);
+		buf[runetochar(buf, &rune)] = 0;
+		js_pushstring(J, buf);
+	} else {
+		js_pushliteral(J, "");
+	}
+	return 1;
+}
+
+static int Sp_charCodeAt(js_State *J, int n)
+{
+	const char *s = js_tostring(J, 0);
+	int pos = js_tointeger(J, 1);
+	s = utfindex(s, pos);
+	if (s) {
+		Rune rune;
+		chartorune(&rune, s);
+		js_pushnumber(J, rune);
+	} else {
+		js_pushnumber(J, NAN);
+	}
+	return 1;
+}
+
 static int S_fromCharCode(js_State *J, int n)
 {
 	int i;
@@ -39,7 +87,7 @@
 	char *s = malloc(n * UTFmax + 1), *p = s;
 	// TODO: guard malloc with try/catch
 	for (i = 0; i < n; i++) {
-		c = js_tonumber(J, i + 1); // TODO: ToUInt16()
+		c = js_tointeger(J, i + 1); // TODO: ToUInt16()
 		p += runetochar(p, &c);
 	}
 	*p = 0;
@@ -62,6 +110,8 @@
 			js_setproperty(J, -2, "constructor");
 			jsB_propf(J, "toString", Sp_toString, 0);
 			jsB_propf(J, "valueOf", Sp_valueOf, 0);
+			jsB_propf(J, "charAt", Sp_charAt, 1);
+			jsB_propf(J, "charCodeAt", Sp_charCodeAt, 1);
 		}
 		js_setproperty(J, -2, "prototype");
 
--- a/jsobject.c
+++ b/jsobject.c
@@ -3,6 +3,7 @@
 #include "jsobject.h"
 #include "jsrun.h"
 #include "jsstate.h"
+#include "jsutf.h"
 
 static js_Object *jsR_newfunction(js_State *J, js_Function *function, js_Environment *scope)
 {
@@ -58,7 +59,7 @@
 		js_Property *ref;
 		ref = jsR_setproperty(J, obj, "length");
 		ref->value.type = JS_TNUMBER;
-		ref->value.u.number = strlen(v);
+		ref->value.u.number = utflen(v);
 		ref->readonly = 1;
 		ref->dontenum = 1;
 		ref->dontconf = 1;
--- a/jsrun.c
+++ b/jsrun.c
@@ -801,8 +801,6 @@
 	jsP_optimize(J, P);
 	F = jsC_compile(J, P);
 
-	jsP_dumpsyntax(J, P);
-
 	jsP_freeparse(J);
 	if (!F) return 1;