shithub: libmujs

Download patch

ref: e23d2070a0a3a1ddd78806525b1596e1785216b4
parent: 88abe2c38c317c76254773085aa7557ec42fbdaf
author: Tor Andersson <tor@ccxvii.net>
date: Sat Jan 11 11:48:46 EST 2014

Check future reserved words in parser to allow them as IdentifierName tokens.

--- a/jslex.c
+++ b/jslex.c
@@ -62,15 +62,6 @@
 	"true", "try", "typeof", "var", "void", "while", "with",
 };
 
-static const char *futurewords[] = {
-	"class", "const", "enum", "export", "extends", "import", "super",
-};
-
-static const char *strictfuturewords[] = {
-	"implements", "interface", "let", "package", "private", "protected",
-	"public", "static", "yield",
-};
-
 static inline int findword(const char *s, const char **list, int num)
 {
 	int l = 0;
@@ -95,12 +86,6 @@
 		J->text = keywords[i];
 		return TK_BREAK + i; /* first keyword + i */
 	}
-
-	if (findword(s, futurewords, nelem(futurewords)) >= 0)
-		return jsP_error(J, "'%s' is a future reserved word", s);
-	if (J->strict && findword(s, strictfuturewords, nelem(strictfuturewords)) >= 0)
-		return jsP_error(J, "'%s' is a strict mode future reserved word", s);
-
 	J->text = js_intern(J, s);
 	return TK_IDENTIFIER;
 }
@@ -606,6 +591,9 @@
 	J->source = source;
 	J->line = 1;
 	J->lasttoken = 0;
+	// FIXME: parse utf-8 proper instead of just skipping BOM
+	if (!strncmp(source, "\357\273\277", 3))
+		J->source += 3;
 }
 
 int jsP_lex(js_State *J)
--- a/jsparse.c
+++ b/jsparse.c
@@ -3,6 +3,8 @@
 #include "jslex.h"
 #include "jsparse.h"
 
+#define nelem(a) (sizeof (a) / sizeof (a)[0])
+
 #define LIST(h)		jsP_newnode(J, AST_LIST, h, 0, 0, 0);
 
 #define EXP0(x)		jsP_newnode(J, EXP_ ## x, 0, 0, 0, 0)
@@ -102,10 +104,46 @@
 
 /* Literals */
 
+static inline int findword(const char *s, const char **list, int num)
+{
+	int l = 0;
+	int r = num - 1;
+	while (l <= r) {
+		int m = (l + r) >> 1;
+		int c = strcmp(s, list[m]);
+		if (c < 0)
+			r = m - 1;
+		else if (c > 0)
+			l = m + 1;
+		else
+			return m;
+	}
+	return -1;
+}
+
+static const char *futurewords[] = {
+	"class", "const", "enum", "export", "extends", "import", "super",
+};
+
+static const char *strictfuturewords[] = {
+	"implements", "interface", "let", "package", "private", "protected",
+	"public", "static", "yield",
+};
+
+static void checkfutureword(js_State *J, const char *s)
+{
+	if (findword(s, futurewords, nelem(futurewords)) >= 0)
+		jsP_error(J, "'%s' is a future reserved word", s);
+	if (J->strict && findword(s, strictfuturewords, nelem(strictfuturewords)) >= 0)
+		jsP_error(J, "'%s' is a strict mode future reserved word", s);
+}
+
 static js_Ast *identifier(js_State *J)
 {
+	js_Ast *a;
 	if (J->lookahead == TK_IDENTIFIER) {
-		js_Ast *a = jsP_newstrnode(J, AST_IDENTIFIER, J->text);
+		checkfutureword(J, J->text);
+		a = jsP_newstrnode(J, AST_IDENTIFIER, J->text);
 		next(J);
 		return a;
 	}