summaryrefslogtreecommitdiffstats
path: root/js/src/vm
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm')
-rw-r--r--js/src/vm/ArgumentsObject.cpp6
-rw-r--r--js/src/vm/AsyncFunction.cpp24
-rw-r--r--js/src/vm/AsyncFunction.h3
-rw-r--r--js/src/vm/CommonPropertyNames.h2
-rw-r--r--js/src/vm/Debugger.cpp11
-rw-r--r--js/src/vm/ErrorObject.cpp69
-rw-r--r--js/src/vm/ErrorObject.h8
-rw-r--r--js/src/vm/ForOfIterator.cpp51
-rw-r--r--js/src/vm/GlobalObject.cpp4
-rw-r--r--js/src/vm/GlobalObject.h17
-rw-r--r--js/src/vm/Interpreter.cpp135
-rw-r--r--js/src/vm/Interpreter.h9
-rw-r--r--js/src/vm/ObjectGroup.cpp4
-rw-r--r--js/src/vm/Opcodes.h55
-rw-r--r--js/src/vm/RegExpObject.cpp13
-rw-r--r--js/src/vm/RegExpObject.h4
-rw-r--r--js/src/vm/SelfHosting.cpp10
-rw-r--r--js/src/vm/Shape.cpp8
-rw-r--r--js/src/vm/Stack.cpp2
-rw-r--r--js/src/vm/StructuredClone.cpp7
-rw-r--r--js/src/vm/TypeInference.cpp2
-rw-r--r--js/src/vm/TypedArrayObject.cpp2
-rw-r--r--js/src/vm/Unicode.cpp879
-rw-r--r--js/src/vm/Unicode.h28
-rw-r--r--js/src/vm/UnicodeNonBMP.h10
-rwxr-xr-xjs/src/vm/make_unicode.py324
26 files changed, 1579 insertions, 108 deletions
diff --git a/js/src/vm/ArgumentsObject.cpp b/js/src/vm/ArgumentsObject.cpp
index d01121ef0..717aa1050 100644
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -676,7 +676,7 @@ UnmappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj, HandleId i
if (argsobj->hasOverriddenLength())
return true;
} else {
- if (!JSID_IS_ATOM(id, cx->names().callee) && !JSID_IS_ATOM(id, cx->names().caller))
+ if (!JSID_IS_ATOM(id, cx->names().callee))
return true;
attrs = JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED;
@@ -709,10 +709,6 @@ UnmappedArgumentsObject::obj_enumerate(JSContext* cx, HandleObject obj)
if (!HasProperty(cx, argsobj, id, &found))
return false;
- id = NameToId(cx->names().caller);
- if (!HasProperty(cx, argsobj, id, &found))
- return false;
-
id = SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator);
if (!HasProperty(cx, argsobj, id, &found))
return false;
diff --git a/js/src/vm/AsyncFunction.cpp b/js/src/vm/AsyncFunction.cpp
index bd0b4f32a..f50c87114 100644
--- a/js/src/vm/AsyncFunction.cpp
+++ b/js/src/vm/AsyncFunction.cpp
@@ -107,19 +107,16 @@ WrappedAsyncFunction(JSContext* cx, unsigned argc, Value* vp)
// the async function's body, replacing `await` with `yield`. `wrapped` is a
// function that is visible to the outside, and handles yielded values.
JSObject*
-js::WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped)
+js::WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleObject proto)
{
MOZ_ASSERT(unwrapped->isStarGenerator());
+ MOZ_ASSERT(proto, "We need an explicit prototype to avoid the default"
+ "%FunctionPrototype% fallback in NewFunctionWithProto().");
// Create a new function with AsyncFunctionPrototype, reusing the name and
// the length of `unwrapped`.
- // Step 1.
- RootedObject proto(cx, GlobalObject::getOrCreateAsyncFunctionPrototype(cx, cx->global()));
- if (!proto)
- return nullptr;
-
- RootedAtom funName(cx, unwrapped->name());
+ RootedAtom funName(cx, unwrapped->explicitName());
uint16_t length;
if (!unwrapped->getLength(cx, &length))
return nullptr;
@@ -133,6 +130,9 @@ js::WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped)
if (!wrapped)
return nullptr;
+ if (unwrapped->hasCompileTimeName())
+ wrapped->setCompileTimeName(unwrapped->compileTimeName());
+
// Link them to each other to make GetWrappedAsyncFunction and
// GetUnwrappedAsyncFunction work.
unwrapped->setExtendedSlot(UNWRAPPED_ASYNC_WRAPPED_SLOT, ObjectValue(*wrapped));
@@ -141,6 +141,16 @@ js::WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped)
return wrapped;
}
+JSObject*
+js::WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped)
+{
+ RootedObject proto(cx, GlobalObject::getOrCreateAsyncFunctionPrototype(cx, cx->global()));
+ if (!proto)
+ return nullptr;
+
+ return WrapAsyncFunctionWithProto(cx, unwrapped, proto);
+}
+
enum class ResumeKind {
Normal,
Throw
diff --git a/js/src/vm/AsyncFunction.h b/js/src/vm/AsyncFunction.h
index ddf81a177..d7f2c1311 100644
--- a/js/src/vm/AsyncFunction.h
+++ b/js/src/vm/AsyncFunction.h
@@ -22,6 +22,9 @@ bool
IsWrappedAsyncFunction(JSFunction* fun);
JSObject*
+WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleObject proto);
+
+JSObject*
WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped);
MOZ_MUST_USE bool
diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h
index bd0705446..e971dc844 100644
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -13,7 +13,7 @@
#define FOR_EACH_COMMON_PROPERTYNAME(macro) \
macro(add, add, "add") \
- macro(allowContentSpread, allowContentSpread, "allowContentSpread") \
+ macro(allowContentIter, allowContentIter, "allowContentIter") \
macro(anonymous, anonymous, "anonymous") \
macro(Any, Any, "Any") \
macro(apply, apply, "apply") \
diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
index b6bc7d62a..d16781326 100644
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -6890,8 +6890,13 @@ class DebuggerSourceGetTextMatcher
bool hasSourceData = ss->hasSourceData();
if (!ss->hasSourceData() && !JSScript::loadSource(cx_, ss, &hasSourceData))
return nullptr;
- return hasSourceData ? ss->substring(cx_, 0, ss->length())
- : NewStringCopyZ<CanGC>(cx_, "[no source]");
+ if (!hasSourceData)
+ return NewStringCopyZ<CanGC>(cx_, "[no source]");
+
+ if (ss->isFunctionBody())
+ return ss->functionBodyString(cx_);
+
+ return ss->substring(cx_, 0, ss->length());
}
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
@@ -9504,7 +9509,7 @@ DebuggerObject::name() const
{
MOZ_ASSERT(isFunction());
- return referent()->as<JSFunction>().name();
+ return referent()->as<JSFunction>().explicitName();
}
JSAtom*
diff --git a/js/src/vm/ErrorObject.cpp b/js/src/vm/ErrorObject.cpp
index 47b61b57b..d8d29830b 100644
--- a/js/src/vm/ErrorObject.cpp
+++ b/js/src/vm/ErrorObject.cpp
@@ -164,29 +164,25 @@ js::ErrorObject::getOrCreateErrorReport(JSContext* cx)
}
static bool
-ErrorObject_checkAndUnwrapThis(JSContext* cx, CallArgs& args, const char* fnName,
- MutableHandle<ErrorObject*> error)
+FindErrorInstanceOrPrototype(JSContext* cx, HandleObject obj, MutableHandleObject result)
{
- const Value& thisValue = args.thisv();
-
- if (!thisValue.isObject()) {
- JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT,
- InformalValueTypeName(thisValue));
- return false;
- }
-
- // Walk up the prototype chain until we find the first ErrorObject that has
- // the slots we need. This allows us to support the poor-man's subclassing
- // of error: Object.create(Error.prototype).
-
- RootedObject target(cx, CheckedUnwrap(&thisValue.toObject()));
+ // Walk up the prototype chain until we find an error object instance or
+ // prototype object. This allows code like:
+ // Object.create(Error.prototype).stack
+ // or
+ // function NYI() { }
+ // NYI.prototype = new Error;
+ // (new NYI).stack
+ // to continue returning stacks that are useless, but at least don't throw.
+
+ RootedObject target(cx, CheckedUnwrap(obj));
if (!target) {
JS_ReportErrorASCII(cx, "Permission denied to access object");
return false;
}
RootedObject proto(cx);
- while (!target->is<ErrorObject>()) {
+ while (!IsErrorProtoKey(StandardProtoKeyOrNull(target))) {
if (!GetPrototype(cx, target, &proto))
return false;
@@ -194,7 +190,7 @@ ErrorObject_checkAndUnwrapThis(JSContext* cx, CallArgs& args, const char* fnName
// We walked the whole prototype chain and did not find an Error
// object.
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
- js_Error_str, fnName, thisValue.toObject().getClass()->name);
+ js_Error_str, "(get stack)", obj->getClass()->name);
return false;
}
@@ -205,19 +201,40 @@ ErrorObject_checkAndUnwrapThis(JSContext* cx, CallArgs& args, const char* fnName
}
}
- error.set(&target->as<ErrorObject>());
+ result.set(target);
return true;
}
+
+static MOZ_ALWAYS_INLINE bool
+IsObject(HandleValue v)
+{
+ return v.isObject();
+}
+
/* static */ bool
js::ErrorObject::getStack(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
- Rooted<ErrorObject*> error(cx);
- if (!ErrorObject_checkAndUnwrapThis(cx, args, "(get stack)", &error))
+ // We accept any object here, because of poor-man's subclassing of Error.
+ return CallNonGenericMethod<IsObject, getStack_impl>(cx, args);
+}
+
+/* static */ bool
+js::ErrorObject::getStack_impl(JSContext* cx, const CallArgs& args)
+{
+ RootedObject thisObj(cx, &args.thisv().toObject());
+
+ RootedObject obj(cx);
+ if (!FindErrorInstanceOrPrototype(cx, thisObj, &obj))
return false;
- RootedObject savedFrameObj(cx, error->stack());
+ if (!obj->is<ErrorObject>()) {
+ args.rval().setString(cx->runtime()->emptyString);
+ return true;
+ }
+
+ RootedObject savedFrameObj(cx, obj->as<ErrorObject>().stack());
RootedString stackString(cx);
if (!BuildStackString(cx, savedFrameObj, &stackString))
return false;
@@ -245,12 +262,6 @@ js::ErrorObject::getStack(JSContext* cx, unsigned argc, Value* vp)
return true;
}
-static MOZ_ALWAYS_INLINE bool
-IsObject(HandleValue v)
-{
- return v.isObject();
-}
-
/* static */ bool
js::ErrorObject::setStack(JSContext* cx, unsigned argc, Value* vp)
{
@@ -262,9 +273,7 @@ js::ErrorObject::setStack(JSContext* cx, unsigned argc, Value* vp)
/* static */ bool
js::ErrorObject::setStack_impl(JSContext* cx, const CallArgs& args)
{
- const Value& thisValue = args.thisv();
- MOZ_ASSERT(thisValue.isObject());
- RootedObject thisObj(cx, &thisValue.toObject());
+ RootedObject thisObj(cx, &args.thisv().toObject());
if (!args.requireAtLeast(cx, "(set stack)", 1))
return false;
diff --git a/js/src/vm/ErrorObject.h b/js/src/vm/ErrorObject.h
index 32a691bb4..0c2d00610 100644
--- a/js/src/vm/ErrorObject.h
+++ b/js/src/vm/ErrorObject.h
@@ -38,9 +38,8 @@ class ErrorObject : public NativeObject
ScopedJSFreePtr<JSErrorReport>* errorReport, HandleString fileName, HandleObject stack,
uint32_t lineNumber, uint32_t columnNumber, HandleString message);
- static const ClassSpec errorClassSpec_;
- static const ClassSpec subErrorClassSpec_;
- static const ClassSpec nonGlobalErrorClassSpec_;
+ static const ClassSpec classSpecs[JSEXN_ERROR_LIMIT];
+ static const Class protoClasses[JSEXN_ERROR_LIMIT];
protected:
static const uint32_t EXNTYPE_SLOT = 0;
@@ -54,7 +53,7 @@ class ErrorObject : public NativeObject
static const uint32_t RESERVED_SLOTS = MESSAGE_SLOT + 1;
public:
- static const Class classes[JSEXN_LIMIT];
+ static const Class classes[JSEXN_ERROR_LIMIT];
static const Class * classForType(JSExnType type) {
MOZ_ASSERT(type < JSEXN_WARN);
@@ -107,6 +106,7 @@ class ErrorObject : public NativeObject
// Getter and setter for the Error.prototype.stack accessor.
static bool getStack(JSContext* cx, unsigned argc, Value* vp);
+ static bool getStack_impl(JSContext* cx, const CallArgs& args);
static bool setStack(JSContext* cx, unsigned argc, Value* vp);
static bool setStack_impl(JSContext* cx, const CallArgs& args);
};
diff --git a/js/src/vm/ForOfIterator.cpp b/js/src/vm/ForOfIterator.cpp
index 7bd521a6a..a67b36774 100644
--- a/js/src/vm/ForOfIterator.cpp
+++ b/js/src/vm/ForOfIterator.cpp
@@ -151,6 +151,57 @@ ForOfIterator::next(MutableHandleValue vp, bool* done)
return GetProperty(cx_, resultObj, resultObj, cx_->names().value, vp);
}
+// ES 2017 draft 0f10dba4ad18de92d47d421f378233a2eae8f077 7.4.6.
+// When completion.[[Type]] is throw.
+void
+ForOfIterator::closeThrow()
+{
+ MOZ_ASSERT(iterator);
+
+ RootedValue completionException(cx_);
+ if (cx_->isExceptionPending()) {
+ if (!GetAndClearException(cx_, &completionException))
+ completionException.setUndefined();
+ }
+
+ // Steps 1-2 (implicit)
+
+ // Step 3 (partial).
+ RootedValue returnVal(cx_);
+ if (!GetProperty(cx_, iterator, iterator, cx_->names().return_, &returnVal))
+ return;
+
+ // Step 4.
+ if (returnVal.isUndefined()) {
+ cx_->setPendingException(completionException);
+ return;
+ }
+
+ // Step 3 (remaining part)
+ if (!returnVal.isObject()) {
+ JS_ReportErrorNumberASCII(cx_, GetErrorMessage, nullptr, JSMSG_RETURN_NOT_CALLABLE);
+ return;
+ }
+ RootedObject returnObj(cx_, &returnVal.toObject());
+ if (!returnObj->isCallable()) {
+ JS_ReportErrorNumberASCII(cx_, GetErrorMessage, nullptr, JSMSG_RETURN_NOT_CALLABLE);
+ return;
+ }
+
+ // Step 5.
+ RootedValue innerResultValue(cx_);
+ if (!js::Call(cx_, returnVal, iterator, &innerResultValue)) {
+ if (cx_->isExceptionPending())
+ cx_->clearPendingException();
+ }
+
+ // Step 6.
+ cx_->setPendingException(completionException);
+
+ // Steps 7-9 (skipped).
+ return;
+}
+
bool
ForOfIterator::materializeArrayIterator()
{
diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp
index 039be2e32..280548cd6 100644
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -802,10 +802,10 @@ GlobalObject::getSelfHostedFunction(JSContext* cx, Handle<GlobalObject*> global,
return false;
if (exists) {
RootedFunction fun(cx, &funVal.toObject().as<JSFunction>());
- if (fun->name() == name)
+ if (fun->explicitName() == name)
return true;
- if (fun->name() == selfHostedName) {
+ if (fun->explicitName() == selfHostedName) {
// This function was initially cloned because it was called by
// other self-hosted code, so the clone kept its self-hosted name,
// instead of getting the name it's intended to have in content
diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h
index 05984bc5f..3534ef2f6 100644
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -427,6 +427,18 @@ class GlobalObject : public NativeObject
return &global->getPrototype(key).toObject();
}
+ static JSFunction*
+ getOrCreateErrorConstructor(JSContext* cx, Handle<GlobalObject*> global) {
+ if (!ensureConstructor(cx, global, JSProto_Error))
+ return nullptr;
+ return &global->getConstructor(JSProto_Error).toObject().as<JSFunction>();
+ }
+
+ static JSObject*
+ getOrCreateErrorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
+ return getOrCreateCustomErrorPrototype(cx, global, JSEXN_ERR);
+ }
+
static NativeObject* getOrCreateSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_Set))
return nullptr;
@@ -1003,10 +1015,7 @@ GenericCreatePrototype(JSContext* cx, JSProtoKey key)
inline JSProtoKey
StandardProtoKeyOrNull(const JSObject* obj)
{
- JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(obj->getClass());
- if (key == JSProto_Error)
- return GetExceptionProtoKey(obj->as<ErrorObject>().type());
- return key;
+ return JSCLASS_CACHED_PROTO_KEY(obj->getClass());
}
JSObject*
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp
index fbf526ae5..b747e4d7a 100644
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -282,8 +282,6 @@ MakeDefaultConstructor(JSContext* cx, JSOp op, JSAtom* atom, HandleObject proto)
ctor->setIsConstructor();
ctor->setIsClassConstructor();
- if (derived)
- ctor->setHasRest();
MOZ_ASSERT(ctor->infallibleIsDefaultClassConstructor(cx));
@@ -1082,6 +1080,9 @@ js::UnwindEnvironmentToTryPc(JSScript* script, JSTryNote* tn)
if (tn->kind == JSTRY_CATCH || tn->kind == JSTRY_FINALLY) {
pc -= JSOP_TRY_LENGTH;
MOZ_ASSERT(*pc == JSOP_TRY);
+ } else if (tn->kind == JSTRY_DESTRUCTURING_ITERCLOSE) {
+ pc -= JSOP_TRY_DESTRUCTURING_ITERCLOSE_LENGTH;
+ MOZ_ASSERT(*pc == JSOP_TRY_DESTRUCTURING_ITERCLOSE);
}
return pc;
}
@@ -1158,6 +1159,7 @@ enum HandleErrorContinuation
static HandleErrorContinuation
ProcessTryNotes(JSContext* cx, EnvironmentIter& ei, InterpreterRegs& regs)
{
+ bool inForOfIterClose = false;
for (TryNoteIterInterpreter tni(cx, regs); !tni.done(); ++tni) {
JSTryNote* tn = *tni;
@@ -1166,10 +1168,38 @@ ProcessTryNotes(JSContext* cx, EnvironmentIter& ei, InterpreterRegs& regs)
/* Catch cannot intercept the closing of a generator. */
if (cx->isClosingGenerator())
break;
+
+ // If IteratorClose due to abnormal completion threw inside a
+ // for-of loop, it is not catchable by try statements inside of
+ // the for-of loop.
+ //
+ // This is handled by this weirdness in the exception handler
+ // instead of in bytecode because it is hard to do so in bytecode:
+ //
+ // 1. IteratorClose emitted due to abnormal completion (break,
+ // throw, return) are emitted inline, at the source location of
+ // the break, throw, or return statement. For example:
+ //
+ // for (x of iter) {
+ // try { return; } catch (e) { }
+ // }
+ //
+ // From the try-note nesting's perspective, the IteratorClose
+ // resulting from |return| is covered by the inner try, when it
+ // should not be.
+ //
+ // 2. Try-catch notes cannot be disjoint. That is, we can't have
+ // multiple notes with disjoint pc ranges jumping to the same
+ // catch block.
+ if (inForOfIterClose)
+ break;
SettleOnTryNote(cx, tn, ei, regs);
return CatchContinuation;
case JSTRY_FINALLY:
+ // See note above.
+ if (inForOfIterClose)
+ break;
SettleOnTryNote(cx, tn, ei, regs);
return FinallyContinuation;
@@ -1191,7 +1221,31 @@ ProcessTryNotes(JSContext* cx, EnvironmentIter& ei, InterpreterRegs& regs)
break;
}
+ case JSTRY_DESTRUCTURING_ITERCLOSE: {
+ // Whether the destructuring iterator is done is at the top of the
+ // stack. The iterator object is second from the top.
+ MOZ_ASSERT(tn->stackDepth > 1);
+ Value* sp = regs.spForStackDepth(tn->stackDepth);
+ RootedValue doneValue(cx, sp[-1]);
+ bool done = ToBoolean(doneValue);
+ if (!done) {
+ RootedObject iterObject(cx, &sp[-2].toObject());
+ if (!IteratorCloseForException(cx, iterObject)) {
+ SettleOnTryNote(cx, tn, ei, regs);
+ return ErrorReturnContinuation;
+ }
+ }
+ break;
+ }
+
+ case JSTRY_FOR_OF_ITERCLOSE:
+ inForOfIterClose = true;
+ break;
+
case JSTRY_FOR_OF:
+ inForOfIterClose = false;
+ break;
+
case JSTRY_LOOP:
break;
@@ -1862,15 +1916,11 @@ CASE(EnableInterruptsPseudoOpcode)
/* Various 1-byte no-ops. */
CASE(JSOP_NOP)
CASE(JSOP_NOP_DESTRUCTURING)
-CASE(JSOP_UNUSED182)
-CASE(JSOP_UNUSED183)
-CASE(JSOP_UNUSED187)
CASE(JSOP_UNUSED192)
CASE(JSOP_UNUSED209)
CASE(JSOP_UNUSED210)
CASE(JSOP_UNUSED211)
-CASE(JSOP_UNUSED219)
-CASE(JSOP_UNUSED220)
+CASE(JSOP_TRY_DESTRUCTURING_ITERCLOSE)
CASE(JSOP_UNUSED221)
CASE(JSOP_UNUSED222)
CASE(JSOP_UNUSED223)
@@ -2159,6 +2209,13 @@ CASE(JSOP_ENDITER)
}
END_CASE(JSOP_ENDITER)
+CASE(JSOP_ISGENCLOSING)
+{
+ bool b = REGS.sp[-1].isMagic(JS_GENERATOR_CLOSING);
+ PUSH_BOOLEAN(b);
+}
+END_CASE(JSOP_ISGENCLOSING)
+
CASE(JSOP_DUP)
{
MOZ_ASSERT(REGS.stackDepth() >= 1);
@@ -2196,6 +2253,16 @@ CASE(JSOP_PICK)
}
END_CASE(JSOP_PICK)
+CASE(JSOP_UNPICK)
+{
+ int i = GET_UINT8(REGS.pc);
+ MOZ_ASSERT(REGS.stackDepth() >= unsigned(i) + 1);
+ Value lval = REGS.sp[-1];
+ memmove(REGS.sp - i, REGS.sp - (i + 1), sizeof(Value) * i);
+ REGS.sp[-(i + 1)] = lval;
+}
+END_CASE(JSOP_UNPICK)
+
CASE(JSOP_BINDGNAME)
CASE(JSOP_BINDNAME)
{
@@ -2597,6 +2664,15 @@ CASE(JSOP_CHECKISOBJ)
}
END_CASE(JSOP_CHECKISOBJ)
+CASE(JSOP_CHECKISCALLABLE)
+{
+ if (!IsCallable(REGS.sp[-1])) {
+ MOZ_ALWAYS_FALSE(ThrowCheckIsCallable(cx, CheckIsCallableKind(GET_UINT8(REGS.pc))));
+ goto error;
+ }
+}
+END_CASE(JSOP_CHECKISCALLABLE)
+
CASE(JSOP_CHECKTHIS)
{
if (REGS.sp[-1].isMagic(JS_UNINITIALIZED_LEXICAL)) {
@@ -3484,6 +3560,19 @@ CASE(JSOP_TOASYNC)
}
END_CASE(JSOP_TOASYNC)
+CASE(JSOP_SETFUNNAME)
+{
+ MOZ_ASSERT(REGS.stackDepth() >= 2);
+ FunctionPrefixKind prefixKind = FunctionPrefixKind(GET_UINT8(REGS.pc));
+ ReservedRooted<Value> name(&rootValue0, REGS.sp[-1]);
+ ReservedRooted<JSFunction*> fun(&rootFunction0, &REGS.sp[-2].toObject().as<JSFunction>());
+ if (!SetFunctionNameIfNoOwnName(cx, fun, name, prefixKind))
+ goto error;
+
+ REGS.sp--;
+}
+END_CASE(JSOP_SETFUNNAME)
+
CASE(JSOP_CALLEE)
MOZ_ASSERT(REGS.fp()->isFunctionFrame());
PUSH_COPY(REGS.fp()->calleev());
@@ -4345,7 +4434,7 @@ js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject envChain,
parent = parent->enclosingEnvironment();
/* ES5 10.5 (NB: with subsequent errata). */
- RootedPropertyName name(cx, fun->name()->asPropertyName());
+ RootedPropertyName name(cx, fun->explicitName()->asPropertyName());
RootedShape shape(cx);
RootedObject pobj(cx);
@@ -4993,7 +5082,7 @@ js::ReportRuntimeLexicalError(JSContext* cx, unsigned errorNumber,
RootedPropertyName name(cx);
if (op == JSOP_THROWSETCALLEE) {
- name = script->functionNonDelazifying()->name()->asPropertyName();
+ name = script->functionNonDelazifying()->explicitName()->asPropertyName();
} else if (IsLocalOp(op)) {
name = FrameSlotName(script, pc)->asPropertyName();
} else if (IsAtomOp(op)) {
@@ -5021,7 +5110,16 @@ js::ThrowCheckIsObject(JSContext* cx, CheckIsObjectKind kind)
{
switch (kind) {
case CheckIsObjectKind::IteratorNext:
- JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NEXT_RETURNED_PRIMITIVE);
+ JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+ JSMSG_ITER_METHOD_RETURNED_PRIMITIVE, "next");
+ break;
+ case CheckIsObjectKind::IteratorReturn:
+ JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+ JSMSG_ITER_METHOD_RETURNED_PRIMITIVE, "return");
+ break;
+ case CheckIsObjectKind::IteratorThrow:
+ JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+ JSMSG_ITER_METHOD_RETURNED_PRIMITIVE, "throw");
break;
case CheckIsObjectKind::GetIterator:
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_GET_ITER_RETURNED_PRIMITIVE);
@@ -5033,6 +5131,19 @@ js::ThrowCheckIsObject(JSContext* cx, CheckIsObjectKind kind)
}
bool
+js::ThrowCheckIsCallable(JSContext* cx, CheckIsCallableKind kind)
+{
+ switch (kind) {
+ case CheckIsCallableKind::IteratorReturn:
+ JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_RETURN_NOT_CALLABLE);
+ break;
+ default:
+ MOZ_CRASH("Unknown kind");
+ }
+ return false;
+}
+
+bool
js::ThrowUninitializedThis(JSContext* cx, AbstractFramePtr frame)
{
RootedFunction fun(cx);
@@ -5061,8 +5172,8 @@ js::ThrowUninitializedThis(JSContext* cx, AbstractFramePtr frame)
if (fun->isDerivedClassConstructor()) {
const char* name = "anonymous";
JSAutoByteString str;
- if (fun->name()) {
- if (!AtomToPrintableString(cx, fun->name(), &str))
+ if (fun->explicitName()) {
+ if (!AtomToPrintableString(cx, fun->explicitName(), &str))
return false;
name = str.ptr();
}
diff --git a/js/src/vm/Interpreter.h b/js/src/vm/Interpreter.h
index 1ffe1fdca..330dbef5f 100644
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -562,12 +562,21 @@ ReportRuntimeRedeclaration(JSContext* cx, HandlePropertyName name, const char* r
enum class CheckIsObjectKind : uint8_t {
IteratorNext,
+ IteratorReturn,
+ IteratorThrow,
GetIterator
};
bool
ThrowCheckIsObject(JSContext* cx, CheckIsObjectKind kind);
+enum class CheckIsCallableKind : uint8_t {
+ IteratorReturn
+};
+
+bool
+ThrowCheckIsCallable(JSContext* cx, CheckIsCallableKind kind);
+
bool
ThrowUninitializedThis(JSContext* cx, AbstractFramePtr frame);
diff --git a/js/src/vm/ObjectGroup.cpp b/js/src/vm/ObjectGroup.cpp
index 7be697fb6..d6a8fcaa4 100644
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -6,6 +6,7 @@
#include "vm/ObjectGroup.h"
+#include "jsexn.h"
#include "jshashutil.h"
#include "jsobj.h"
@@ -578,11 +579,10 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp,
AddTypePropertyId(cx, group, nullptr, NameToId(names.lastIndex), TypeSet::Int32Type());
} else if (clasp == &StringObject::class_) {
AddTypePropertyId(cx, group, nullptr, NameToId(names.length), TypeSet::Int32Type());
- } else if (ErrorObject::isErrorClass((clasp))) {
+ } else if (ErrorObject::isErrorClass(clasp)) {
AddTypePropertyId(cx, group, nullptr, NameToId(names.fileName), TypeSet::StringType());
AddTypePropertyId(cx, group, nullptr, NameToId(names.lineNumber), TypeSet::Int32Type());
AddTypePropertyId(cx, group, nullptr, NameToId(names.columnNumber), TypeSet::Int32Type());
- AddTypePropertyId(cx, group, nullptr, NameToId(names.stack), TypeSet::StringType());
}
return group;
diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h
index 18ae6f073..4b044c8d8 100644
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -1870,9 +1870,24 @@
* Stack: =>
*/ \
macro(JSOP_POPVARENV, 181, "popvarenv", NULL, 1, 0, 0, JOF_BYTE) \
- macro(JSOP_UNUSED182, 182,"unused182", NULL, 1, 0, 0, JOF_BYTE) \
- macro(JSOP_UNUSED183, 183,"unused183", NULL, 1, 0, 0, JOF_BYTE) \
- \
+ /*
+ * Pops the top two values on the stack as 'name' and 'fun', defines the
+ * name of 'fun' to 'name' with prefix if any, and pushes 'fun' back onto
+ * the stack.
+ * Category: Statements
+ * Type: Function
+ * Operands: uint8_t prefixKind
+ * Stack: fun, name => fun
+ */ \
+ macro(JSOP_SETFUNNAME, 182,"setfunname", NULL, 2, 2, 1, JOF_UINT8) \
+ /*
+ * Moves the top of the stack value under the nth element of the stack.
+ * Category: Operators
+ * Type: Stack Operations
+ * Operands: uint8_t n
+ * Stack: v[n], v[n-1], ..., v[1], v[0] => v[0], v[n], v[n-1], ..., v[1]
+ */ \
+ macro(JSOP_UNPICK, 183,"unpick", NULL, 2, 0, 0, JOF_UINT8) \
/*
* Pops the top of stack value, pushes property of it onto the stack.
*
@@ -1901,8 +1916,16 @@
* Stack: => this
*/ \
macro(JSOP_GLOBALTHIS, 186,"globalthis", NULL, 1, 0, 1, JOF_BYTE) \
- macro(JSOP_UNUSED187, 187,"unused187", NULL, 1, 0, 0, JOF_BYTE) \
- \
+ /*
+ * Pushes a boolean indicating whether the top of the stack is
+ * MagicValue(JS_GENERATOR_CLOSING).
+ *
+ * Category: Statements
+ * Type: For-In Statement
+ * Operands:
+ * Stack: val => val, res
+ */ \
+ macro(JSOP_ISGENCLOSING, 187, "isgenclosing", NULL, 1, 1, 2, JOF_BYTE) \
/*
* Pushes unsigned 24-bit int immediate integer operand onto the stack.
* Category: Literals
@@ -2178,8 +2201,26 @@
*/ \
macro(JSOP_HOLE, 218, "hole", NULL, 1, 0, 1, JOF_BYTE) \
\
- macro(JSOP_UNUSED219, 219,"unused219", NULL, 1, 0, 0, JOF_BYTE) \
- macro(JSOP_UNUSED220, 220,"unused220", NULL, 1, 0, 0, JOF_BYTE) \
+ /*
+ * Checks that the top value on the stack is callable, and throws a
+ * TypeError if not. The operand 'kind' is used only to generate an
+ * appropriate error message.
+ * Category: Statements
+ * Type: Function
+ * Operands: uint8_t kind
+ * Stack: result => result, callable
+ */ \
+ macro(JSOP_CHECKISCALLABLE, 219, "checkiscallable", NULL, 2, 1, 1, JOF_UINT8) \
+ \
+ /*
+ * No-op used by the exception unwinder to determine the correct
+ * environment to unwind to when performing IteratorClose due to
+ * destructuring.
+ * Category: Other
+ * Operands:
+ * Stack: =>
+ */ \
+ macro(JSOP_TRY_DESTRUCTURING_ITERCLOSE, 220, "try-destructuring-iterclose", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED221, 221,"unused221", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED222, 222,"unused222", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED223, 223,"unused223", NULL, 1, 0, 0, JOF_BYTE) \
diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp
index 97f1163aa..e0b44e1eb 100644
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -196,6 +196,12 @@ RegExpObject::trace(JSTracer* trc, JSObject* obj)
}
}
+static JSObject*
+CreateRegExpPrototype(JSContext* cx, JSProtoKey key)
+{
+ return cx->global()->createBlankPrototype(cx, &RegExpObject::protoClass_);
+}
+
static const ClassOps RegExpObjectClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
@@ -229,6 +235,13 @@ const Class RegExpObject::class_ = {
&RegExpObjectClassSpec
};
+const Class RegExpObject::protoClass_ = {
+ js_Object_str,
+ JSCLASS_HAS_CACHED_PROTO(JSProto_RegExp),
+ JS_NULL_CLASS_OPS,
+ &RegExpObjectClassSpec
+};
+
RegExpObject*
RegExpObject::create(ExclusiveContext* cx, const char16_t* chars, size_t length, RegExpFlag flags,
TokenStream* tokenStream, LifoAlloc& alloc)
diff --git a/js/src/vm/RegExpObject.h b/js/src/vm/RegExpObject.h
index d6dde1668..dc428a973 100644
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -79,9 +79,6 @@ RegExpAlloc(ExclusiveContext* cx, HandleObject proto = nullptr);
extern JSObject*
CloneRegExpObject(JSContext* cx, JSObject* regexp);
-extern JSObject*
-CreateRegExpPrototype(JSContext* cx, JSProtoKey key);
-
/*
* A RegExpShared is the compiled representation of a regexp. A RegExpShared is
* potentially pointed to by multiple RegExpObjects. Additionally, C++ code may
@@ -411,6 +408,7 @@ class RegExpObject : public NativeObject
static const unsigned PRIVATE_SLOT = 3;
static const Class class_;
+ static const Class protoClass_;
// The maximum number of pairs a MatchResult can have, without having to
// allocate a bigger MatchResult.
diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp
index 6737e774c..bf49f2268 100644
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2878,7 +2878,7 @@ CloneObject(JSContext* cx, HandleNativeObject selfHostedObject)
RootedObject clone(cx);
if (selfHostedObject->is<JSFunction>()) {
RootedFunction selfHostedFunction(cx, &selfHostedObject->as<JSFunction>());
- bool hasName = selfHostedFunction->name() != nullptr;
+ bool hasName = selfHostedFunction->explicitName() != nullptr;
// Arrow functions use the first extended slot for their lexical |this| value.
MOZ_ASSERT(!selfHostedFunction->isArrow());
@@ -2894,7 +2894,7 @@ CloneObject(JSContext* cx, HandleNativeObject selfHostedObject)
// self-hosting compartment has to be stored on the clone.
if (clone && hasName) {
clone->as<JSFunction>().setExtendedSlot(LAZY_FUNCTION_NAME_SLOT,
- StringValue(selfHostedFunction->name()));
+ StringValue(selfHostedFunction->explicitName()));
}
} else if (selfHostedObject->is<RegExpObject>()) {
RegExpObject& reobj = selfHostedObject->as<RegExpObject>();
@@ -2977,10 +2977,10 @@ JSRuntime::createLazySelfHostedFunctionClone(JSContext* cx, HandlePropertyName s
return false;
if (!selfHostedFun->isClassConstructor() && !selfHostedFun->hasGuessedAtom() &&
- selfHostedFun->name() != selfHostedName)
+ selfHostedFun->explicitName() != selfHostedName)
{
MOZ_ASSERT(selfHostedFun->getExtendedSlot(HAS_SELFHOSTED_CANONICAL_NAME_SLOT).toBoolean());
- funName = selfHostedFun->name();
+ funName = selfHostedFun->explicitName();
}
fun.set(NewScriptedFunction(cx, nargs, JSFunction::INTERPRETED_LAZY,
@@ -3022,7 +3022,7 @@ JSRuntime::cloneSelfHostedFunctionScript(JSContext* cx, HandlePropertyName name,
MOZ_ASSERT(!targetFun->isInterpretedLazy());
MOZ_ASSERT(sourceFun->nargs() == targetFun->nargs());
- MOZ_ASSERT(sourceFun->hasRest() == targetFun->hasRest());
+ MOZ_ASSERT(sourceScript->hasRest() == targetFun->nonLazyScript()->hasRest());
// The target function might have been relazified after its flags changed.
targetFun->setFlags(targetFun->flags() | sourceFun->flags());
diff --git a/js/src/vm/Shape.cpp b/js/src/vm/Shape.cpp
index a64dc529a..306a2c540 100644
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -1214,6 +1214,10 @@ JSObject::setFlags(ExclusiveContext* cx, BaseShape::Flag flags, GenerateShape ge
RootedObject self(cx, this);
+ Shape* existingShape = self->ensureShape(cx);
+ if (!existingShape)
+ return false;
+
if (isNative() && as<NativeObject>().inDictionaryMode()) {
if (generateShape == GENERATE_SHAPE && !as<NativeObject>().generateOwnShape(cx))
return false;
@@ -1227,10 +1231,6 @@ JSObject::setFlags(ExclusiveContext* cx, BaseShape::Flag flags, GenerateShape ge
return true;
}
- Shape* existingShape = self->ensureShape(cx);
- if (!existingShape)
- return false;
-
Shape* newShape = Shape::setObjectFlags(cx, flags, self->taggedProto(), existingShape);
if (!newShape)
return false;
diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp
index 439bb1ed4..87e95c893 100644
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -85,7 +85,7 @@ InterpreterFrame::isNonGlobalEvalFrame() const
JSObject*
InterpreterFrame::createRestParameter(JSContext* cx)
{
- MOZ_ASSERT(callee().hasRest());
+ MOZ_ASSERT(script()->hasRest());
unsigned nformal = callee().nargs() - 1, nactual = numActualArgs();
unsigned nrest = (nactual > nformal) ? nactual - nformal : 0;
Value* restvp = argv() + nformal;
diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp
index 4b01cda85..3a062c3b8 100644
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -2188,12 +2188,14 @@ JSStructuredCloneReader::readHeader()
return in.reportTruncated();
if (tag != SCTAG_HEADER) {
- // Old structured clone buffer. We must have read it from disk or
- // somewhere, so we can assume it's scope-compatible.
+ // Old structured clone buffer. We must have read it from disk.
+ storedScope = JS::StructuredCloneScope::DifferentProcess;
return true;
}
MOZ_ALWAYS_TRUE(in.readPair(&tag, &data));
+ storedScope = JS::StructuredCloneScope(data);
+
if (data != uint32_t(JS::StructuredCloneScope::SameProcessSameThread) &&
data != uint32_t(JS::StructuredCloneScope::SameProcessDifferentThread) &&
data != uint32_t(JS::StructuredCloneScope::DifferentProcess))
@@ -2202,7 +2204,6 @@ JSStructuredCloneReader::readHeader()
"invalid structured clone scope");
return false;
}
- storedScope = JS::StructuredCloneScope(data);
if (storedScope < allowedScope) {
JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_BAD_SERIALIZED_DATA,
"incompatible structured clone scope");
diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp
index 2a7762e4f..3d09c7464 100644
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -4541,7 +4541,7 @@ TypeScript::printTypes(JSContext* cx, HandleScript script) const
uintptr_t(script.get()), script->filename(), script->lineno());
if (script->functionNonDelazifying()) {
- if (JSAtom* name = script->functionNonDelazifying()->name())
+ if (JSAtom* name = script->functionNonDelazifying()->explicitName())
name->dumpCharsNoNewline();
}
diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp
index 9d4ee94c6..ae97be0de 100644
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -2870,7 +2870,7 @@ bool
DataViewObject::defineGetter(JSContext* cx, PropertyName* name, HandleNativeObject proto)
{
RootedId id(cx, NameToId(name));
- RootedAtom atom(cx, IdToFunctionName(cx, id, "get"));
+ RootedAtom atom(cx, IdToFunctionName(cx, id, FunctionPrefixKind::Get));
if (!atom)
return false;
unsigned attrs = JSPROP_SHARED | JSPROP_GETTER;
diff --git a/js/src/vm/Unicode.cpp b/js/src/vm/Unicode.cpp
index f4acf8f31..82541c231 100644
--- a/js/src/vm/Unicode.cpp
+++ b/js/src/vm/Unicode.cpp
@@ -1748,3 +1748,882 @@ const uint8_t unicode::folding_index2[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
+bool
+js::unicode::IsIdentifierStartNonBMP(uint32_t codePoint)
+{
+ if (codePoint >= 0x10000 && codePoint <= 0x1000b)
+ return true;
+ if (codePoint >= 0x1000d && codePoint <= 0x10026)
+ return true;
+ if (codePoint >= 0x10028 && codePoint <= 0x1003a)
+ return true;
+ if (codePoint >= 0x1003c && codePoint <= 0x1003d)
+ return true;
+ if (codePoint >= 0x1003f && codePoint <= 0x1004d)
+ return true;
+ if (codePoint >= 0x10050 && codePoint <= 0x1005d)
+ return true;
+ if (codePoint >= 0x10080 && codePoint <= 0x100fa)
+ return true;
+ if (codePoint >= 0x10140 && codePoint <= 0x10174)
+ return true;
+ if (codePoint >= 0x10280 && codePoint <= 0x1029c)
+ return true;
+ if (codePoint >= 0x102a0 && codePoint <= 0x102d0)
+ return true;
+ if (codePoint >= 0x10300 && codePoint <= 0x1031f)
+ return true;
+ if (codePoint >= 0x10330 && codePoint <= 0x1034a)
+ return true;
+ if (codePoint >= 0x10350 && codePoint <= 0x10375)
+ return true;
+ if (codePoint >= 0x10380 && codePoint <= 0x1039d)
+ return true;
+ if (codePoint >= 0x103a0 && codePoint <= 0x103c3)
+ return true;
+ if (codePoint >= 0x103c8 && codePoint <= 0x103cf)
+ return true;
+ if (codePoint >= 0x103d1 && codePoint <= 0x103d5)
+ return true;
+ if (codePoint >= 0x10400 && codePoint <= 0x1049d)
+ return true;
+ if (codePoint >= 0x104b0 && codePoint <= 0x104d3)
+ return true;
+ if (codePoint >= 0x104d8 && codePoint <= 0x104fb)
+ return true;
+ if (codePoint >= 0x10500 && codePoint <= 0x10527)
+ return true;
+ if (codePoint >= 0x10530 && codePoint <= 0x10563)
+ return true;
+ if (codePoint >= 0x10600 && codePoint <= 0x10736)
+ return true;
+ if (codePoint >= 0x10740 && codePoint <= 0x10755)
+ return true;
+ if (codePoint >= 0x10760 && codePoint <= 0x10767)
+ return true;
+ if (codePoint >= 0x10800 && codePoint <= 0x10805)
+ return true;
+ if (codePoint >= 0x10808 && codePoint <= 0x10808)
+ return true;
+ if (codePoint >= 0x1080a && codePoint <= 0x10835)
+ return true;
+ if (codePoint >= 0x10837 && codePoint <= 0x10838)
+ return true;
+ if (codePoint >= 0x1083c && codePoint <= 0x1083c)
+ return true;
+ if (codePoint >= 0x1083f && codePoint <= 0x10855)
+ return true;
+ if (codePoint >= 0x10860 && codePoint <= 0x10876)
+ return true;
+ if (codePoint >= 0x10880 && codePoint <= 0x1089e)
+ return true;
+ if (codePoint >= 0x108e0 && codePoint <= 0x108f2)
+ return true;
+ if (codePoint >= 0x108f4 && codePoint <= 0x108f5)
+ return true;
+ if (codePoint >= 0x10900 && codePoint <= 0x10915)
+ return true;
+ if (codePoint >= 0x10920 && codePoint <= 0x10939)
+ return true;
+ if (codePoint >= 0x10980 && codePoint <= 0x109b7)
+ return true;
+ if (codePoint >= 0x109be && codePoint <= 0x109bf)
+ return true;
+ if (codePoint >= 0x10a00 && codePoint <= 0x10a00)
+ return true;
+ if (codePoint >= 0x10a10 && codePoint <= 0x10a13)
+ return true;
+ if (codePoint >= 0x10a15 && codePoint <= 0x10a17)
+ return true;
+ if (codePoint >= 0x10a19 && codePoint <= 0x10a33)
+ return true;
+ if (codePoint >= 0x10a60 && codePoint <= 0x10a7c)
+ return true;
+ if (codePoint >= 0x10a80 && codePoint <= 0x10a9c)
+ return true;
+ if (codePoint >= 0x10ac0 && codePoint <= 0x10ac7)
+ return true;
+ if (codePoint >= 0x10ac9 && codePoint <= 0x10ae4)
+ return true;
+ if (codePoint >= 0x10b00 && codePoint <= 0x10b35)
+ return true;
+ if (codePoint >= 0x10b40 && codePoint <= 0x10b55)
+ return true;
+ if (codePoint >= 0x10b60 && codePoint <= 0x10b72)
+ return true;
+ if (codePoint >= 0x10b80 && codePoint <= 0x10b91)
+ return true;
+ if (codePoint >= 0x10c00 && codePoint <= 0x10c48)
+ return true;
+ if (codePoint >= 0x10c80 && codePoint <= 0x10cb2)
+ return true;
+ if (codePoint >= 0x10cc0 && codePoint <= 0x10cf2)
+ return true;
+ if (codePoint >= 0x11003 && codePoint <= 0x11037)
+ return true;
+ if (codePoint >= 0x11083 && codePoint <= 0x110af)
+ return true;
+ if (codePoint >= 0x110d0 && codePoint <= 0x110e8)
+ return true;
+ if (codePoint >= 0x11103 && codePoint <= 0x11126)
+ return true;
+ if (codePoint >= 0x11150 && codePoint <= 0x11172)
+ return true;
+ if (codePoint >= 0x11176 && codePoint <= 0x11176)
+ return true;
+ if (codePoint >= 0x11183 && codePoint <= 0x111b2)
+ return true;
+ if (codePoint >= 0x111c1 && codePoint <= 0x111c4)
+ return true;
+ if (codePoint >= 0x111da && codePoint <= 0x111da)
+ return true;
+ if (codePoint >= 0x111dc && codePoint <= 0x111dc)
+ return true;
+ if (codePoint >= 0x11200 && codePoint <= 0x11211)
+ return true;
+ if (codePoint >= 0x11213 && codePoint <= 0x1122b)
+ return true;
+ if (codePoint >= 0x11280 && codePoint <= 0x11286)
+ return true;
+ if (codePoint >= 0x11288 && codePoint <= 0x11288)
+ return true;
+ if (codePoint >= 0x1128a && codePoint <= 0x1128d)
+ return true;
+ if (codePoint >= 0x1128f && codePoint <= 0x1129d)
+ return true;
+ if (codePoint >= 0x1129f && codePoint <= 0x112a8)
+ return true;
+ if (codePoint >= 0x112b0 && codePoint <= 0x112de)
+ return true;
+ if (codePoint >= 0x11305 && codePoint <= 0x1130c)
+ return true;
+ if (codePoint >= 0x1130f && codePoint <= 0x11310)
+ return true;
+ if (codePoint >= 0x11313 && codePoint <= 0x11328)
+ return true;
+ if (codePoint >= 0x1132a && codePoint <= 0x11330)
+ return true;
+ if (codePoint >= 0x11332 && codePoint <= 0x11333)
+ return true;
+ if (codePoint >= 0x11335 && codePoint <= 0x11339)
+ return true;
+ if (codePoint >= 0x1133d && codePoint <= 0x1133d)
+ return true;
+ if (codePoint >= 0x11350 && codePoint <= 0x11350)
+ return true;
+ if (codePoint >= 0x1135d && codePoint <= 0x11361)
+ return true;
+ if (codePoint >= 0x11400 && codePoint <= 0x11434)
+ return true;
+ if (codePoint >= 0x11447 && codePoint <= 0x1144a)
+ return true;
+ if (codePoint >= 0x11480 && codePoint <= 0x114af)
+ return true;
+ if (codePoint >= 0x114c4 && codePoint <= 0x114c5)
+ return true;
+ if (codePoint >= 0x114c7 && codePoint <= 0x114c7)
+ return true;
+ if (codePoint >= 0x11580 && codePoint <= 0x115ae)
+ return true;
+ if (codePoint >= 0x115d8 && codePoint <= 0x115db)
+ return true;
+ if (codePoint >= 0x11600 && codePoint <= 0x1162f)
+ return true;
+ if (codePoint >= 0x11644 && codePoint <= 0x11644)
+ return true;
+ if (codePoint >= 0x11680 && codePoint <= 0x116aa)
+ return true;
+ if (codePoint >= 0x11700 && codePoint <= 0x11719)
+ return true;
+ if (codePoint >= 0x118a0 && codePoint <= 0x118df)
+ return true;
+ if (codePoint >= 0x118ff && codePoint <= 0x118ff)
+ return true;
+ if (codePoint >= 0x11ac0 && codePoint <= 0x11af8)
+ return true;
+ if (codePoint >= 0x11c00 && codePoint <= 0x11c08)
+ return true;
+ if (codePoint >= 0x11c0a && codePoint <= 0x11c2e)
+ return true;
+ if (codePoint >= 0x11c40 && codePoint <= 0x11c40)
+ return true;
+ if (codePoint >= 0x11c72 && codePoint <= 0x11c8f)
+ return true;
+ if (codePoint >= 0x12000 && codePoint <= 0x12399)
+ return true;
+ if (codePoint >= 0x12400 && codePoint <= 0x1246e)
+ return true;
+ if (codePoint >= 0x12480 && codePoint <= 0x12543)
+ return true;
+ if (codePoint >= 0x13000 && codePoint <= 0x1342e)
+ return true;
+ if (codePoint >= 0x14400 && codePoint <= 0x14646)
+ return true;
+ if (codePoint >= 0x16800 && codePoint <= 0x16a38)
+ return true;
+ if (codePoint >= 0x16a40 && codePoint <= 0x16a5e)
+ return true;
+ if (codePoint >= 0x16ad0 && codePoint <= 0x16aed)
+ return true;
+ if (codePoint >= 0x16b00 && codePoint <= 0x16b2f)
+ return true;
+ if (codePoint >= 0x16b40 && codePoint <= 0x16b43)
+ return true;
+ if (codePoint >= 0x16b63 && codePoint <= 0x16b77)
+ return true;
+ if (codePoint >= 0x16b7d && codePoint <= 0x16b8f)
+ return true;
+ if (codePoint >= 0x16f00 && codePoint <= 0x16f44)
+ return true;
+ if (codePoint >= 0x16f50 && codePoint <= 0x16f50)
+ return true;
+ if (codePoint >= 0x16f93 && codePoint <= 0x16f9f)
+ return true;
+ if (codePoint >= 0x16fe0 && codePoint <= 0x16fe0)
+ return true;
+ if (codePoint >= 0x17000 && codePoint <= 0x187ec)
+ return true;
+ if (codePoint >= 0x18800 && codePoint <= 0x18af2)
+ return true;
+ if (codePoint >= 0x1b000 && codePoint <= 0x1b001)
+ return true;
+ if (codePoint >= 0x1bc00 && codePoint <= 0x1bc6a)
+ return true;
+ if (codePoint >= 0x1bc70 && codePoint <= 0x1bc7c)
+ return true;
+ if (codePoint >= 0x1bc80 && codePoint <= 0x1bc88)
+ return true;
+ if (codePoint >= 0x1bc90 && codePoint <= 0x1bc99)
+ return true;
+ if (codePoint >= 0x1d400 && codePoint <= 0x1d454)
+ return true;
+ if (codePoint >= 0x1d456 && codePoint <= 0x1d49c)
+ return true;
+ if (codePoint >= 0x1d49e && codePoint <= 0x1d49f)
+ return true;
+ if (codePoint >= 0x1d4a2 && codePoint <= 0x1d4a2)
+ return true;
+ if (codePoint >= 0x1d4a5 && codePoint <= 0x1d4a6)
+ return true;
+ if (codePoint >= 0x1d4a9 && codePoint <= 0x1d4ac)
+ return true;
+ if (codePoint >= 0x1d4ae && codePoint <= 0x1d4b9)
+ return true;
+ if (codePoint >= 0x1d4bb && codePoint <= 0x1d4bb)
+ return true;
+ if (codePoint >= 0x1d4bd && codePoint <= 0x1d4c3)
+ return true;
+ if (codePoint >= 0x1d4c5 && codePoint <= 0x1d505)
+ return true;
+ if (codePoint >= 0x1d507 && codePoint <= 0x1d50a)
+ return true;
+ if (codePoint >= 0x1d50d && codePoint <= 0x1d514)
+ return true;
+ if (codePoint >= 0x1d516 && codePoint <= 0x1d51c)
+ return true;
+ if (codePoint >= 0x1d51e && codePoint <= 0x1d539)
+ return true;
+ if (codePoint >= 0x1d53b && codePoint <= 0x1d53e)
+ return true;
+ if (codePoint >= 0x1d540 && codePoint <= 0x1d544)
+ return true;
+ if (codePoint >= 0x1d546 && codePoint <= 0x1d546)
+ return true;
+ if (codePoint >= 0x1d54a && codePoint <= 0x1d550)
+ return true;
+ if (codePoint >= 0x1d552 && codePoint <= 0x1d6a5)
+ return true;
+ if (codePoint >= 0x1d6a8 && codePoint <= 0x1d6c0)
+ return true;
+ if (codePoint >= 0x1d6c2 && codePoint <= 0x1d6da)
+ return true;
+ if (codePoint >= 0x1d6dc && codePoint <= 0x1d6fa)
+ return true;
+ if (codePoint >= 0x1d6fc && codePoint <= 0x1d714)
+ return true;
+ if (codePoint >= 0x1d716 && codePoint <= 0x1d734)
+ return true;
+ if (codePoint >= 0x1d736 && codePoint <= 0x1d74e)
+ return true;
+ if (codePoint >= 0x1d750 && codePoint <= 0x1d76e)
+ return true;
+ if (codePoint >= 0x1d770 && codePoint <= 0x1d788)
+ return true;
+ if (codePoint >= 0x1d78a && codePoint <= 0x1d7a8)
+ return true;
+ if (codePoint >= 0x1d7aa && codePoint <= 0x1d7c2)
+ return true;
+ if (codePoint >= 0x1d7c4 && codePoint <= 0x1d7cb)
+ return true;
+ if (codePoint >= 0x1e800 && codePoint <= 0x1e8c4)
+ return true;
+ if (codePoint >= 0x1e900 && codePoint <= 0x1e943)
+ return true;
+ if (codePoint >= 0x1ee00 && codePoint <= 0x1ee03)
+ return true;
+ if (codePoint >= 0x1ee05 && codePoint <= 0x1ee1f)
+ return true;
+ if (codePoint >= 0x1ee21 && codePoint <= 0x1ee22)
+ return true;
+ if (codePoint >= 0x1ee24 && codePoint <= 0x1ee24)
+ return true;
+ if (codePoint >= 0x1ee27 && codePoint <= 0x1ee27)
+ return true;
+ if (codePoint >= 0x1ee29 && codePoint <= 0x1ee32)
+ return true;
+ if (codePoint >= 0x1ee34 && codePoint <= 0x1ee37)
+ return true;
+ if (codePoint >= 0x1ee39 && codePoint <= 0x1ee39)
+ return true;
+ if (codePoint >= 0x1ee3b && codePoint <= 0x1ee3b)
+ return true;
+ if (codePoint >= 0x1ee42 && codePoint <= 0x1ee42)
+ return true;
+ if (codePoint >= 0x1ee47 && codePoint <= 0x1ee47)
+ return true;
+ if (codePoint >= 0x1ee49 && codePoint <= 0x1ee49)
+ return true;
+ if (codePoint >= 0x1ee4b && codePoint <= 0x1ee4b)
+ return true;
+ if (codePoint >= 0x1ee4d && codePoint <= 0x1ee4f)
+ return true;
+ if (codePoint >= 0x1ee51 && codePoint <= 0x1ee52)
+ return true;
+ if (codePoint >= 0x1ee54 && codePoint <= 0x1ee54)
+ return true;
+ if (codePoint >= 0x1ee57 && codePoint <= 0x1ee57)
+ return true;
+ if (codePoint >= 0x1ee59 && codePoint <= 0x1ee59)
+ return true;
+ if (codePoint >= 0x1ee5b && codePoint <= 0x1ee5b)
+ return true;
+ if (codePoint >= 0x1ee5d && codePoint <= 0x1ee5d)
+ return true;
+ if (codePoint >= 0x1ee5f && codePoint <= 0x1ee5f)
+ return true;
+ if (codePoint >= 0x1ee61 && codePoint <= 0x1ee62)
+ return true;
+ if (codePoint >= 0x1ee64 && codePoint <= 0x1ee64)
+ return true;
+ if (codePoint >= 0x1ee67 && codePoint <= 0x1ee6a)
+ return true;
+ if (codePoint >= 0x1ee6c && codePoint <= 0x1ee72)
+ return true;
+ if (codePoint >= 0x1ee74 && codePoint <= 0x1ee77)
+ return true;
+ if (codePoint >= 0x1ee79 && codePoint <= 0x1ee7c)
+ return true;
+ if (codePoint >= 0x1ee7e && codePoint <= 0x1ee7e)
+ return true;
+ if (codePoint >= 0x1ee80 && codePoint <= 0x1ee89)
+ return true;
+ if (codePoint >= 0x1ee8b && codePoint <= 0x1ee9b)
+ return true;
+ if (codePoint >= 0x1eea1 && codePoint <= 0x1eea3)
+ return true;
+ if (codePoint >= 0x1eea5 && codePoint <= 0x1eea9)
+ return true;
+ if (codePoint >= 0x1eeab && codePoint <= 0x1eebb)
+ return true;
+ if (codePoint >= 0x20000 && codePoint <= 0x2a6d6)
+ return true;
+ if (codePoint >= 0x2a700 && codePoint <= 0x2b734)
+ return true;
+ if (codePoint >= 0x2b740 && codePoint <= 0x2b81d)
+ return true;
+ if (codePoint >= 0x2b820 && codePoint <= 0x2cea1)
+ return true;
+ if (codePoint >= 0x2f800 && codePoint <= 0x2fa1d)
+ return true;
+ return false;
+}
+
+bool
+js::unicode::IsIdentifierPartNonBMP(uint32_t codePoint)
+{
+ if (codePoint >= 0x10000 && codePoint <= 0x1000b)
+ return true;
+ if (codePoint >= 0x1000d && codePoint <= 0x10026)
+ return true;
+ if (codePoint >= 0x10028 && codePoint <= 0x1003a)
+ return true;
+ if (codePoint >= 0x1003c && codePoint <= 0x1003d)
+ return true;
+ if (codePoint >= 0x1003f && codePoint <= 0x1004d)
+ return true;
+ if (codePoint >= 0x10050 && codePoint <= 0x1005d)
+ return true;
+ if (codePoint >= 0x10080 && codePoint <= 0x100fa)
+ return true;
+ if (codePoint >= 0x10140 && codePoint <= 0x10174)
+ return true;
+ if (codePoint >= 0x101fd && codePoint <= 0x101fd)
+ return true;
+ if (codePoint >= 0x10280 && codePoint <= 0x1029c)
+ return true;
+ if (codePoint >= 0x102a0 && codePoint <= 0x102d0)
+ return true;
+ if (codePoint >= 0x102e0 && codePoint <= 0x102e0)
+ return true;
+ if (codePoint >= 0x10300 && codePoint <= 0x1031f)
+ return true;
+ if (codePoint >= 0x10330 && codePoint <= 0x1034a)
+ return true;
+ if (codePoint >= 0x10350 && codePoint <= 0x1037a)
+ return true;
+ if (codePoint >= 0x10380 && codePoint <= 0x1039d)
+ return true;
+ if (codePoint >= 0x103a0 && codePoint <= 0x103c3)
+ return true;
+ if (codePoint >= 0x103c8 && codePoint <= 0x103cf)
+ return true;
+ if (codePoint >= 0x103d1 && codePoint <= 0x103d5)
+ return true;
+ if (codePoint >= 0x10400 && codePoint <= 0x1049d)
+ return true;
+ if (codePoint >= 0x104a0 && codePoint <= 0x104a9)
+ return true;
+ if (codePoint >= 0x104b0 && codePoint <= 0x104d3)
+ return true;
+ if (codePoint >= 0x104d8 && codePoint <= 0x104fb)
+ return true;
+ if (codePoint >= 0x10500 && codePoint <= 0x10527)
+ return true;
+ if (codePoint >= 0x10530 && codePoint <= 0x10563)
+ return true;
+ if (codePoint >= 0x10600 && codePoint <= 0x10736)
+ return true;
+ if (codePoint >= 0x10740 && codePoint <= 0x10755)
+ return true;
+ if (codePoint >= 0x10760 && codePoint <= 0x10767)
+ return true;
+ if (codePoint >= 0x10800 && codePoint <= 0x10805)
+ return true;
+ if (codePoint >= 0x10808 && codePoint <= 0x10808)
+ return true;
+ if (codePoint >= 0x1080a && codePoint <= 0x10835)
+ return true;
+ if (codePoint >= 0x10837 && codePoint <= 0x10838)
+ return true;
+ if (codePoint >= 0x1083c && codePoint <= 0x1083c)
+ return true;
+ if (codePoint >= 0x1083f && codePoint <= 0x10855)
+ return true;
+ if (codePoint >= 0x10860 && codePoint <= 0x10876)
+ return true;
+ if (codePoint >= 0x10880 && codePoint <= 0x1089e)
+ return true;
+ if (codePoint >= 0x108e0 && codePoint <= 0x108f2)
+ return true;
+ if (codePoint >= 0x108f4 && codePoint <= 0x108f5)
+ return true;
+ if (codePoint >= 0x10900 && codePoint <= 0x10915)
+ return true;
+ if (codePoint >= 0x10920 && codePoint <= 0x10939)
+ return true;
+ if (codePoint >= 0x10980 && codePoint <= 0x109b7)
+ return true;
+ if (codePoint >= 0x109be && codePoint <= 0x109bf)
+ return true;
+ if (codePoint >= 0x10a00 && codePoint <= 0x10a03)
+ return true;
+ if (codePoint >= 0x10a05 && codePoint <= 0x10a06)
+ return true;
+ if (codePoint >= 0x10a0c && codePoint <= 0x10a13)
+ return true;
+ if (codePoint >= 0x10a15 && codePoint <= 0x10a17)
+ return true;
+ if (codePoint >= 0x10a19 && codePoint <= 0x10a33)
+ return true;
+ if (codePoint >= 0x10a38 && codePoint <= 0x10a3a)
+ return true;
+ if (codePoint >= 0x10a3f && codePoint <= 0x10a3f)
+ return true;
+ if (codePoint >= 0x10a60 && codePoint <= 0x10a7c)
+ return true;
+ if (codePoint >= 0x10a80 && codePoint <= 0x10a9c)
+ return true;
+ if (codePoint >= 0x10ac0 && codePoint <= 0x10ac7)
+ return true;
+ if (codePoint >= 0x10ac9 && codePoint <= 0x10ae6)
+ return true;
+ if (codePoint >= 0x10b00 && codePoint <= 0x10b35)
+ return true;
+ if (codePoint >= 0x10b40 && codePoint <= 0x10b55)
+ return true;
+ if (codePoint >= 0x10b60 && codePoint <= 0x10b72)
+ return true;
+ if (codePoint >= 0x10b80 && codePoint <= 0x10b91)
+ return true;
+ if (codePoint >= 0x10c00 && codePoint <= 0x10c48)
+ return true;
+ if (codePoint >= 0x10c80 && codePoint <= 0x10cb2)
+ return true;
+ if (codePoint >= 0x10cc0 && codePoint <= 0x10cf2)
+ return true;
+ if (codePoint >= 0x11000 && codePoint <= 0x11046)
+ return true;
+ if (codePoint >= 0x11066 && codePoint <= 0x1106f)
+ return true;
+ if (codePoint >= 0x1107f && codePoint <= 0x110ba)
+ return true;
+ if (codePoint >= 0x110d0 && codePoint <= 0x110e8)
+ return true;
+ if (codePoint >= 0x110f0 && codePoint <= 0x110f9)
+ return true;
+ if (codePoint >= 0x11100 && codePoint <= 0x11134)
+ return true;
+ if (codePoint >= 0x11136 && codePoint <= 0x1113f)
+ return true;
+ if (codePoint >= 0x11150 && codePoint <= 0x11173)
+ return true;
+ if (codePoint >= 0x11176 && codePoint <= 0x11176)
+ return true;
+ if (codePoint >= 0x11180 && codePoint <= 0x111c4)
+ return true;
+ if (codePoint >= 0x111ca && codePoint <= 0x111cc)
+ return true;
+ if (codePoint >= 0x111d0 && codePoint <= 0x111da)
+ return true;
+ if (codePoint >= 0x111dc && codePoint <= 0x111dc)
+ return true;
+ if (codePoint >= 0x11200 && codePoint <= 0x11211)
+ return true;
+ if (codePoint >= 0x11213 && codePoint <= 0x11237)
+ return true;
+ if (codePoint >= 0x1123e && codePoint <= 0x1123e)
+ return true;
+ if (codePoint >= 0x11280 && codePoint <= 0x11286)
+ return true;
+ if (codePoint >= 0x11288 && codePoint <= 0x11288)
+ return true;
+ if (codePoint >= 0x1128a && codePoint <= 0x1128d)
+ return true;
+ if (codePoint >= 0x1128f && codePoint <= 0x1129d)
+ return true;
+ if (codePoint >= 0x1129f && codePoint <= 0x112a8)
+ return true;
+ if (codePoint >= 0x112b0 && codePoint <= 0x112ea)
+ return true;
+ if (codePoint >= 0x112f0 && codePoint <= 0x112f9)
+ return true;
+ if (codePoint >= 0x11300 && codePoint <= 0x11303)
+ return true;
+ if (codePoint >= 0x11305 && codePoint <= 0x1130c)
+ return true;
+ if (codePoint >= 0x1130f && codePoint <= 0x11310)
+ return true;
+ if (codePoint >= 0x11313 && codePoint <= 0x11328)
+ return true;
+ if (codePoint >= 0x1132a && codePoint <= 0x11330)
+ return true;
+ if (codePoint >= 0x11332 && codePoint <= 0x11333)
+ return true;
+ if (codePoint >= 0x11335 && codePoint <= 0x11339)
+ return true;
+ if (codePoint >= 0x1133c && codePoint <= 0x11344)
+ return true;
+ if (codePoint >= 0x11347 && codePoint <= 0x11348)
+ return true;
+ if (codePoint >= 0x1134b && codePoint <= 0x1134d)
+ return true;
+ if (codePoint >= 0x11350 && codePoint <= 0x11350)
+ return true;
+ if (codePoint >= 0x11357 && codePoint <= 0x11357)
+ return true;
+ if (codePoint >= 0x1135d && codePoint <= 0x11363)
+ return true;
+ if (codePoint >= 0x11366 && codePoint <= 0x1136c)
+ return true;
+ if (codePoint >= 0x11370 && codePoint <= 0x11374)
+ return true;
+ if (codePoint >= 0x11400 && codePoint <= 0x1144a)
+ return true;
+ if (codePoint >= 0x11450 && codePoint <= 0x11459)
+ return true;
+ if (codePoint >= 0x11480 && codePoint <= 0x114c5)
+ return true;
+ if (codePoint >= 0x114c7 && codePoint <= 0x114c7)
+ return true;
+ if (codePoint >= 0x114d0 && codePoint <= 0x114d9)
+ return true;
+ if (codePoint >= 0x11580 && codePoint <= 0x115b5)
+ return true;
+ if (codePoint >= 0x115b8 && codePoint <= 0x115c0)
+ return true;
+ if (codePoint >= 0x115d8 && codePoint <= 0x115dd)
+ return true;
+ if (codePoint >= 0x11600 && codePoint <= 0x11640)
+ return true;
+ if (codePoint >= 0x11644 && codePoint <= 0x11644)
+ return true;
+ if (codePoint >= 0x11650 && codePoint <= 0x11659)
+ return true;
+ if (codePoint >= 0x11680 && codePoint <= 0x116b7)
+ return true;
+ if (codePoint >= 0x116c0 && codePoint <= 0x116c9)
+ return true;
+ if (codePoint >= 0x11700 && codePoint <= 0x11719)
+ return true;
+ if (codePoint >= 0x1171d && codePoint <= 0x1172b)
+ return true;
+ if (codePoint >= 0x11730 && codePoint <= 0x11739)
+ return true;
+ if (codePoint >= 0x118a0 && codePoint <= 0x118e9)
+ return true;
+ if (codePoint >= 0x118ff && codePoint <= 0x118ff)
+ return true;
+ if (codePoint >= 0x11ac0 && codePoint <= 0x11af8)
+ return true;
+ if (codePoint >= 0x11c00 && codePoint <= 0x11c08)
+ return true;
+ if (codePoint >= 0x11c0a && codePoint <= 0x11c36)
+ return true;
+ if (codePoint >= 0x11c38 && codePoint <= 0x11c40)
+ return true;
+ if (codePoint >= 0x11c50 && codePoint <= 0x11c59)
+ return true;
+ if (codePoint >= 0x11c72 && codePoint <= 0x11c8f)
+ return true;
+ if (codePoint >= 0x11c92 && codePoint <= 0x11ca7)
+ return true;
+ if (codePoint >= 0x11ca9 && codePoint <= 0x11cb6)
+ return true;
+ if (codePoint >= 0x12000 && codePoint <= 0x12399)
+ return true;
+ if (codePoint >= 0x12400 && codePoint <= 0x1246e)
+ return true;
+ if (codePoint >= 0x12480 && codePoint <= 0x12543)
+ return true;
+ if (codePoint >= 0x13000 && codePoint <= 0x1342e)
+ return true;
+ if (codePoint >= 0x14400 && codePoint <= 0x14646)
+ return true;
+ if (codePoint >= 0x16800 && codePoint <= 0x16a38)
+ return true;
+ if (codePoint >= 0x16a40 && codePoint <= 0x16a5e)
+ return true;
+ if (codePoint >= 0x16a60 && codePoint <= 0x16a69)
+ return true;
+ if (codePoint >= 0x16ad0 && codePoint <= 0x16aed)
+ return true;
+ if (codePoint >= 0x16af0 && codePoint <= 0x16af4)
+ return true;
+ if (codePoint >= 0x16b00 && codePoint <= 0x16b36)
+ return true;
+ if (codePoint >= 0x16b40 && codePoint <= 0x16b43)
+ return true;
+ if (codePoint >= 0x16b50 && codePoint <= 0x16b59)
+ return true;
+ if (codePoint >= 0x16b63 && codePoint <= 0x16b77)
+ return true;
+ if (codePoint >= 0x16b7d && codePoint <= 0x16b8f)
+ return true;
+ if (codePoint >= 0x16f00 && codePoint <= 0x16f44)
+ return true;
+ if (codePoint >= 0x16f50 && codePoint <= 0x16f7e)
+ return true;
+ if (codePoint >= 0x16f8f && codePoint <= 0x16f9f)
+ return true;
+ if (codePoint >= 0x16fe0 && codePoint <= 0x16fe0)
+ return true;
+ if (codePoint >= 0x17000 && codePoint <= 0x187ec)
+ return true;
+ if (codePoint >= 0x18800 && codePoint <= 0x18af2)
+ return true;
+ if (codePoint >= 0x1b000 && codePoint <= 0x1b001)
+ return true;
+ if (codePoint >= 0x1bc00 && codePoint <= 0x1bc6a)
+ return true;
+ if (codePoint >= 0x1bc70 && codePoint <= 0x1bc7c)
+ return true;
+ if (codePoint >= 0x1bc80 && codePoint <= 0x1bc88)
+ return true;
+ if (codePoint >= 0x1bc90 && codePoint <= 0x1bc99)
+ return true;
+ if (codePoint >= 0x1bc9d && codePoint <= 0x1bc9e)
+ return true;
+ if (codePoint >= 0x1d165 && codePoint <= 0x1d169)
+ return true;
+ if (codePoint >= 0x1d16d && codePoint <= 0x1d172)
+ return true;
+ if (codePoint >= 0x1d17b && codePoint <= 0x1d182)
+ return true;
+ if (codePoint >= 0x1d185 && codePoint <= 0x1d18b)
+ return true;
+ if (codePoint >= 0x1d1aa && codePoint <= 0x1d1ad)
+ return true;
+ if (codePoint >= 0x1d242 && codePoint <= 0x1d244)
+ return true;
+ if (codePoint >= 0x1d400 && codePoint <= 0x1d454)
+ return true;
+ if (codePoint >= 0x1d456 && codePoint <= 0x1d49c)
+ return true;
+ if (codePoint >= 0x1d49e && codePoint <= 0x1d49f)
+ return true;
+ if (codePoint >= 0x1d4a2 && codePoint <= 0x1d4a2)
+ return true;
+ if (codePoint >= 0x1d4a5 && codePoint <= 0x1d4a6)
+ return true;
+ if (codePoint >= 0x1d4a9 && codePoint <= 0x1d4ac)
+ return true;
+ if (codePoint >= 0x1d4ae && codePoint <= 0x1d4b9)
+ return true;
+ if (codePoint >= 0x1d4bb && codePoint <= 0x1d4bb)
+ return true;
+ if (codePoint >= 0x1d4bd && codePoint <= 0x1d4c3)
+ return true;
+ if (codePoint >= 0x1d4c5 && codePoint <= 0x1d505)
+ return true;
+ if (codePoint >= 0x1d507 && codePoint <= 0x1d50a)
+ return true;
+ if (codePoint >= 0x1d50d && codePoint <= 0x1d514)
+ return true;
+ if (codePoint >= 0x1d516 && codePoint <= 0x1d51c)
+ return true;
+ if (codePoint >= 0x1d51e && codePoint <= 0x1d539)
+ return true;
+ if (codePoint >= 0x1d53b && codePoint <= 0x1d53e)
+ return true;
+ if (codePoint >= 0x1d540 && codePoint <= 0x1d544)
+ return true;
+ if (codePoint >= 0x1d546 && codePoint <= 0x1d546)
+ return true;
+ if (codePoint >= 0x1d54a && codePoint <= 0x1d550)
+ return true;
+ if (codePoint >= 0x1d552 && codePoint <= 0x1d6a5)
+ return true;
+ if (codePoint >= 0x1d6a8 && codePoint <= 0x1d6c0)
+ return true;
+ if (codePoint >= 0x1d6c2 && codePoint <= 0x1d6da)
+ return true;
+ if (codePoint >= 0x1d6dc && codePoint <= 0x1d6fa)
+ return true;
+ if (codePoint >= 0x1d6fc && codePoint <= 0x1d714)
+ return true;
+ if (codePoint >= 0x1d716 && codePoint <= 0x1d734)
+ return true;
+ if (codePoint >= 0x1d736 && codePoint <= 0x1d74e)
+ return true;
+ if (codePoint >= 0x1d750 && codePoint <= 0x1d76e)
+ return true;
+ if (codePoint >= 0x1d770 && codePoint <= 0x1d788)
+ return true;
+ if (codePoint >= 0x1d78a && codePoint <= 0x1d7a8)
+ return true;
+ if (codePoint >= 0x1d7aa && codePoint <= 0x1d7c2)
+ return true;
+ if (codePoint >= 0x1d7c4 && codePoint <= 0x1d7cb)
+ return true;
+ if (codePoint >= 0x1d7ce && codePoint <= 0x1d7ff)
+ return true;
+ if (codePoint >= 0x1da00 && codePoint <= 0x1da36)
+ return true;
+ if (codePoint >= 0x1da3b && codePoint <= 0x1da6c)
+ return true;
+ if (codePoint >= 0x1da75 && codePoint <= 0x1da75)
+ return true;
+ if (codePoint >= 0x1da84 && codePoint <= 0x1da84)
+ return true;
+ if (codePoint >= 0x1da9b && codePoint <= 0x1da9f)
+ return true;
+ if (codePoint >= 0x1daa1 && codePoint <= 0x1daaf)
+ return true;
+ if (codePoint >= 0x1e000 && codePoint <= 0x1e006)
+ return true;
+ if (codePoint >= 0x1e008 && codePoint <= 0x1e018)
+ return true;
+ if (codePoint >= 0x1e01b && codePoint <= 0x1e021)
+ return true;
+ if (codePoint >= 0x1e023 && codePoint <= 0x1e024)
+ return true;
+ if (codePoint >= 0x1e026 && codePoint <= 0x1e02a)
+ return true;
+ if (codePoint >= 0x1e800 && codePoint <= 0x1e8c4)
+ return true;
+ if (codePoint >= 0x1e8d0 && codePoint <= 0x1e8d6)
+ return true;
+ if (codePoint >= 0x1e900 && codePoint <= 0x1e94a)
+ return true;
+ if (codePoint >= 0x1e950 && codePoint <= 0x1e959)
+ return true;
+ if (codePoint >= 0x1ee00 && codePoint <= 0x1ee03)
+ return true;
+ if (codePoint >= 0x1ee05 && codePoint <= 0x1ee1f)
+ return true;
+ if (codePoint >= 0x1ee21 && codePoint <= 0x1ee22)
+ return true;
+ if (codePoint >= 0x1ee24 && codePoint <= 0x1ee24)
+ return true;
+ if (codePoint >= 0x1ee27 && codePoint <= 0x1ee27)
+ return true;
+ if (codePoint >= 0x1ee29 && codePoint <= 0x1ee32)
+ return true;
+ if (codePoint >= 0x1ee34 && codePoint <= 0x1ee37)
+ return true;
+ if (codePoint >= 0x1ee39 && codePoint <= 0x1ee39)
+ return true;
+ if (codePoint >= 0x1ee3b && codePoint <= 0x1ee3b)
+ return true;
+ if (codePoint >= 0x1ee42 && codePoint <= 0x1ee42)
+ return true;
+ if (codePoint >= 0x1ee47 && codePoint <= 0x1ee47)
+ return true;
+ if (codePoint >= 0x1ee49 && codePoint <= 0x1ee49)
+ return true;
+ if (codePoint >= 0x1ee4b && codePoint <= 0x1ee4b)
+ return true;
+ if (codePoint >= 0x1ee4d && codePoint <= 0x1ee4f)
+ return true;
+ if (codePoint >= 0x1ee51 && codePoint <= 0x1ee52)
+ return true;
+ if (codePoint >= 0x1ee54 && codePoint <= 0x1ee54)
+ return true;
+ if (codePoint >= 0x1ee57 && codePoint <= 0x1ee57)
+ return true;
+ if (codePoint >= 0x1ee59 && codePoint <= 0x1ee59)
+ return true;
+ if (codePoint >= 0x1ee5b && codePoint <= 0x1ee5b)
+ return true;
+ if (codePoint >= 0x1ee5d && codePoint <= 0x1ee5d)
+ return true;
+ if (codePoint >= 0x1ee5f && codePoint <= 0x1ee5f)
+ return true;
+ if (codePoint >= 0x1ee61 && codePoint <= 0x1ee62)
+ return true;
+ if (codePoint >= 0x1ee64 && codePoint <= 0x1ee64)
+ return true;
+ if (codePoint >= 0x1ee67 && codePoint <= 0x1ee6a)
+ return true;
+ if (codePoint >= 0x1ee6c && codePoint <= 0x1ee72)
+ return true;
+ if (codePoint >= 0x1ee74 && codePoint <= 0x1ee77)
+ return true;
+ if (codePoint >= 0x1ee79 && codePoint <= 0x1ee7c)
+ return true;
+ if (codePoint >= 0x1ee7e && codePoint <= 0x1ee7e)
+ return true;
+ if (codePoint >= 0x1ee80 && codePoint <= 0x1ee89)
+ return true;
+ if (codePoint >= 0x1ee8b && codePoint <= 0x1ee9b)
+ return true;
+ if (codePoint >= 0x1eea1 && codePoint <= 0x1eea3)
+ return true;
+ if (codePoint >= 0x1eea5 && codePoint <= 0x1eea9)
+ return true;
+ if (codePoint >= 0x1eeab && codePoint <= 0x1eebb)
+ return true;
+ if (codePoint >= 0x20000 && codePoint <= 0x2a6d6)
+ return true;
+ if (codePoint >= 0x2a700 && codePoint <= 0x2b734)
+ return true;
+ if (codePoint >= 0x2b740 && codePoint <= 0x2b81d)
+ return true;
+ if (codePoint >= 0x2b820 && codePoint <= 0x2cea1)
+ return true;
+ if (codePoint >= 0x2f800 && codePoint <= 0x2fa1d)
+ return true;
+ if (codePoint >= 0xe0100 && codePoint <= 0xe01ef)
+ return true;
+ return false;
+}
diff --git a/js/src/vm/Unicode.h b/js/src/vm/Unicode.h
index 8b538d06d..bdac848fb 100644
--- a/js/src/vm/Unicode.h
+++ b/js/src/vm/Unicode.h
@@ -143,11 +143,15 @@ IsIdentifierStart(char16_t ch)
return CharInfo(ch).isUnicodeIDStart();
}
+bool
+IsIdentifierStartNonBMP(uint32_t codePoint);
+
inline bool
IsIdentifierStart(uint32_t codePoint)
{
- // TODO: Supplemental code points not yet supported (bug 1197230).
- return codePoint <= UTF16Max && IsIdentifierStart(char16_t(codePoint));
+ if (MOZ_UNLIKELY(codePoint > UTF16Max))
+ return IsIdentifierStartNonBMP(codePoint);
+ return IsIdentifierStart(char16_t(codePoint));
}
inline bool
@@ -170,11 +174,16 @@ IsIdentifierPart(char16_t ch)
return CharInfo(ch).isUnicodeIDContinue();
}
+
+bool
+IsIdentifierPartNonBMP(uint32_t codePoint);
+
inline bool
IsIdentifierPart(uint32_t codePoint)
{
- // TODO: Supplemental code points not yet supported (bug 1197230).
- return codePoint <= UTF16Max && IsIdentifierPart(char16_t(codePoint));
+ if (MOZ_UNLIKELY(codePoint > UTF16Max))
+ return IsIdentifierPartNonBMP(codePoint);
+ return IsIdentifierPart(char16_t(codePoint));
}
inline bool
@@ -183,6 +192,17 @@ IsUnicodeIDStart(char16_t ch)
return CharInfo(ch).isUnicodeIDStart();
}
+bool
+IsUnicodeIDStartNonBMP(uint32_t codePoint);
+
+inline bool
+IsUnicodeIDStart(uint32_t codePoint)
+{
+ if (MOZ_UNLIKELY(codePoint > UTF16Max))
+ return IsIdentifierStartNonBMP(codePoint);
+ return IsUnicodeIDStart(char16_t(codePoint));
+}
+
inline bool
IsSpace(char16_t ch)
{
diff --git a/js/src/vm/UnicodeNonBMP.h b/js/src/vm/UnicodeNonBMP.h
index 6cc64cde4..f99e227cd 100644
--- a/js/src/vm/UnicodeNonBMP.h
+++ b/js/src/vm/UnicodeNonBMP.h
@@ -10,6 +10,16 @@
#ifndef vm_UnicodeNonBMP_h
#define vm_UnicodeNonBMP_h
+// |macro| receives the following arguments
+// macro(FROM, TO, LEAD, TRAIL_FROM, TRAIL_TO, DIFF)
+// FROM: code point where the range starts
+// TO: code point where the range ends
+// LEAD: common lead surrogate of FROM and TO
+// TRAIL_FROM: trail surrogate of FROM
+// TRAIL_FROM: trail surrogate of TO
+// DIFF: the difference between the code point in the range and
+// converted code point
+
#define FOR_EACH_NON_BMP_LOWERCASE(macro) \
macro(0x10400, 0x10427, 0xd801, 0xdc00, 0xdc27, 40) \
macro(0x104b0, 0x104d3, 0xd801, 0xdcb0, 0xdcd3, 40) \
diff --git a/js/src/vm/make_unicode.py b/js/src/vm/make_unicode.py
index 5565d7d14..83f0d004b 100755
--- a/js/src/vm/make_unicode.py
+++ b/js/src/vm/make_unicode.py
@@ -133,6 +133,17 @@ def read_derived_core_properties(derived_core_properties):
for char in range(int(start, 16), int(end, 16) + 1):
yield (char, char_property)
+def int_ranges(ints):
+ """ Yields consecutive ranges (inclusive) from integer values. """
+ from itertools import tee, izip_longest
+
+ (a, b) = tee(sorted(ints))
+ start = next(b)
+ for (curr, succ) in izip_longest(a, b):
+ if curr + 1 != succ:
+ yield (start, curr)
+ start = succ
+
def utf16_encode(code):
NonBMPMin = 0x10000
LeadSurrogateMin = 0xD800
@@ -144,37 +155,65 @@ def utf16_encode(code):
return lead, trail
def make_non_bmp_convert_macro(out_file, name, convert_map):
+ # Find continuous range in convert_map.
convert_list = []
entry = None
for code in sorted(convert_map.keys()):
+ lead, trail = utf16_encode(code)
converted = convert_map[code]
diff = converted - code
- if entry and code == entry['code'] + entry['length'] and diff == entry['diff']:
+ if (entry and code == entry['code'] + entry['length'] and
+ diff == entry['diff'] and lead == entry['lead']):
+
entry['length'] += 1
continue
- entry = { 'code': code, 'diff': diff, 'length': 1 }
+ entry = {
+ 'code': code,
+ 'diff': diff,
+ 'length': 1,
+ 'lead': lead,
+ 'trail': trail,
+ }
convert_list.append(entry)
+ # Generate macro call for each range.
lines = []
for entry in convert_list:
from_code = entry['code']
to_code = entry['code'] + entry['length'] - 1
diff = entry['diff']
- from_lead, from_trail = utf16_encode(from_code)
- to_lead, to_trail = utf16_encode(to_code)
-
- assert from_lead == to_lead
+ lead = entry['lead']
+ from_trail = entry['trail']
+ to_trail = entry['trail'] + entry['length'] - 1
lines.append(' macro(0x{:x}, 0x{:x}, 0x{:x}, 0x{:x}, 0x{:x}, {:d})'.format(
- from_code, to_code, from_lead, from_trail, to_trail, diff))
+ from_code, to_code, lead, from_trail, to_trail, diff))
out_file.write('#define FOR_EACH_NON_BMP_{}(macro) \\\n'.format(name))
out_file.write(' \\\n'.join(lines))
out_file.write('\n')
+def for_each_non_bmp_group(group_set):
+ # Find continuous range in group_set.
+ group_list = []
+ entry = None
+ for code in sorted(group_set.keys()):
+ if entry and code == entry['code'] + entry['length']:
+ entry['length'] += 1
+ continue
+
+ entry = {
+ 'code': code,
+ 'length': 1
+ }
+ group_list.append(entry)
+
+ for entry in group_list:
+ yield (entry['code'], entry['code'] + entry['length'] - 1)
+
def process_derived_core_properties(derived_core_properties):
id_start = set()
id_continue = set()
@@ -203,6 +242,9 @@ def process_unicode_data(unicode_data, derived_core_properties):
non_bmp_lower_map = {}
non_bmp_upper_map = {}
+ non_bmp_id_start_set = {}
+ non_bmp_id_cont_set = {}
+ non_bmp_space_set = {}
(id_start, id_continue) = process_derived_core_properties(derived_core_properties)
@@ -235,6 +277,13 @@ def process_unicode_data(unicode_data, derived_core_properties):
non_bmp_lower_map[code] = lower
if code != upper:
non_bmp_upper_map[code] = upper
+ if category == 'Zs':
+ non_bmp_space_set[code] = 1
+ test_space_table.append(code)
+ if code in id_start:
+ non_bmp_id_start_set[code] = 1
+ if code in id_continue:
+ non_bmp_id_cont_set[code] = 1
continue
# we combine whitespace and lineterminators because in pratice we don't need them separated
@@ -304,6 +353,8 @@ def process_unicode_data(unicode_data, derived_core_properties):
table, index,
same_upper_table, same_upper_index,
non_bmp_lower_map, non_bmp_upper_map,
+ non_bmp_space_set,
+ non_bmp_id_start_set, non_bmp_id_cont_set,
test_table, test_space_table,
)
@@ -401,6 +452,16 @@ def make_non_bmp_file(version,
#ifndef vm_UnicodeNonBMP_h
#define vm_UnicodeNonBMP_h
+// |macro| receives the following arguments
+// macro(FROM, TO, LEAD, TRAIL_FROM, TRAIL_TO, DIFF)
+// FROM: code point where the range starts
+// TO: code point where the range ends
+// LEAD: common lead surrogate of FROM and TO
+// TRAIL_FROM: trail surrogate of FROM
+// TRAIL_FROM: trail surrogate of TO
+// DIFF: the difference between the code point in the range and
+// converted code point
+
""")
make_non_bmp_convert_macro(non_bmp_file, 'LOWERCASE', non_bmp_lower_map)
@@ -514,7 +575,9 @@ if (typeof reportCompare === "function")
def make_unicode_file(version,
table, index,
same_upper_table, same_upper_index,
- folding_table, folding_index):
+ folding_table, folding_index,
+ non_bmp_space_set,
+ non_bmp_id_start_set, non_bmp_id_cont_set):
index1, index2, shift = splitbins(index)
# Don't forget to update CharInfo in Unicode.h if you need to change this
@@ -671,6 +734,43 @@ def make_unicode_file(version,
dump(folding_index2, 'folding_index2', data_file)
data_file.write('\n')
+ # If the following assert fails, it means space character is added to
+ # non-BMP area. In that case the following code should be uncommented
+ # and the corresponding code should be added to frontend.
+ assert len(non_bmp_space_set.keys()) == 0
+
+ data_file.write("""\
+bool
+js::unicode::IsIdentifierStartNonBMP(uint32_t codePoint)
+{
+""")
+
+ for (from_code, to_code) in for_each_non_bmp_group(non_bmp_id_start_set):
+ data_file.write("""\
+ if (codePoint >= 0x{:x} && codePoint <= 0x{:x})
+ return true;
+""".format(from_code, to_code))
+
+ data_file.write("""\
+ return false;
+}
+
+bool
+js::unicode::IsIdentifierPartNonBMP(uint32_t codePoint)
+{
+""")
+
+ for (from_code, to_code) in for_each_non_bmp_group(non_bmp_id_cont_set):
+ data_file.write("""\
+ if (codePoint >= 0x{:x} && codePoint <= 0x{:x})
+ return true;
+""".format(from_code, to_code))
+
+ data_file.write("""\
+ return false;
+}
+""")
+
def getsize(data):
""" return smallest possible integer size for the given array """
maxdata = max(data)
@@ -740,6 +840,204 @@ def splitbins(t):
assert t[i] == t2[(t1[i >> shift] << shift) + (i & mask)]
return best
+def make_irregexp_tables(version,
+ table, index,
+ folding_table, folding_index,
+ test_table):
+ import string
+ from functools import partial
+ from itertools import chain, ifilter, imap
+
+ MAX_ASCII = 0x7F
+ MAX_LATIN1 = 0xFF
+ LEAD_SURROGATE_MIN = 0xD800
+ TRAIL_SURROGATE_MAX = 0xDFFF
+
+ def hex2(n):
+ assert 0 <= n and n < 16**2
+ return '0x{:02X}'.format(n)
+
+ def hex4(n):
+ assert 0 <= n and n < 16**4
+ return '0x{:04X}'.format(n)
+
+ def uhex4(n):
+ assert 0 <= n and n < 16**4
+ return 'U+{:04X}'.format(n)
+
+ def case_info(code):
+ assert 0 <= code and code <= MAX_BMP
+ (upper, lower, flags) = table[index[code]]
+ return ((code + upper) & 0xffff, (code + lower) & 0xffff, flags)
+
+ def is_space(code):
+ (_, _, flags) = case_info(code)
+ return bool(flags & FLAG_SPACE)
+
+ def to_upper(code):
+ (upper, _, _) = case_info(code)
+ return upper
+
+ def casefold(code):
+ assert 0 <= code and code <= MAX_BMP
+ (folding, _, _, _) = folding_table[folding_index[code]]
+ return (code + folding) & 0xffff
+
+ def casefolds_to_ascii(code):
+ return casefold(code) <= MAX_ASCII
+
+ def casefolds_to_latin1(code):
+ return casefold(code) <= MAX_LATIN1
+
+ def casemaps_to_nonlatin1(code):
+ upper = to_upper(code)
+ return upper > MAX_LATIN1
+
+ def char_name(code):
+ assert 0 <= code and code <= MAX_BMP
+ if code not in test_table:
+ return '<Unused>'
+ if code == LEAD_SURROGATE_MIN:
+ return '<Lead Surrogate Min>'
+ if code == TRAIL_SURROGATE_MAX:
+ return '<Trail Surrogate Max>'
+ (_, _, name, alias) = test_table[code]
+ return name if not name.startswith('<') else alias
+
+ def write_character_range(println, name, characters):
+ char_ranges = list(int_ranges(characters))
+ println('')
+ println('const int js::irregexp::k{}Ranges[] = {{'.format(name))
+ for (start, end) in char_ranges:
+ s_name = char_name(start)
+ e_name = char_name(end)
+ println(' {}, {} + 1, // {}'.format(hex4(start), hex4(end),
+ '{}..{}'.format(s_name, e_name)
+ if start != end else s_name))
+ println(' {} + 1'.format(hex4(MAX_BMP)))
+ println('};')
+ println('const int js::irregexp::k{}RangeCount = {};'.format(name,
+ len(char_ranges) * 2 + 1))
+
+ def write_character_test(println, test, consequent, default):
+ # Latin1 characters which, when case-mapped through
+ # String.prototype.toUpperCase(), canonicalize to a non-Latin1 character.
+ # ES2017, §21.2.2.8.2 Runtime Semantics: Canonicalize
+ casemapped_to_nonlatin1 = ifilter(casemaps_to_nonlatin1, xrange(0, MAX_LATIN1 + 1))
+
+ def casemap_closure(ch):
+ upper = to_upper(ch)
+ return (ch, [c for c in xrange(MAX_LATIN1 + 1, MAX_BMP + 1) if upper == to_upper(c)])
+
+ # Mapping from Latin1 characters to the list of case map equivalent
+ # non-Latin1 characters.
+ casemap_for_latin1 = dict(chain(imap(casemap_closure, casemapped_to_nonlatin1)))
+
+ # Non-latin1 characters which, when Unicode case-folded, canonicalize to
+ # a Latin1 character.
+ # ES2017, §21.2.2.8.2 Runtime Semantics: Canonicalize
+ casefolded_to_latin1 = ifilter(casefolds_to_latin1, xrange(MAX_LATIN1 + 1, MAX_BMP + 1))
+
+ println(' if (unicode) {')
+ for ch in casefolded_to_latin1:
+ casefolded = casefold(ch)
+ # Skip if also handled below for case mapping.
+ if casefolded in casemap_for_latin1 and ch in casemap_for_latin1[casefolded]:
+ continue
+ println(' // "{}" case folds to "{}".'.format(char_name(ch),
+ char_name(casefolded)))
+ println(' if ({})'.format(test(ch)))
+ println(' return {};'.format(consequent(casefolded)))
+ println(' }')
+ println('')
+ for (ch, casemapped_chars) in casemap_for_latin1.iteritems():
+ for casemapped in casemapped_chars:
+ println(' // "{}" case maps to "{}".'.format(char_name(casemapped),
+ char_name(ch)))
+ println(' if ({})'.format(' || '.join(imap(test, casemapped_chars))))
+ println(' return {};'.format(consequent(ch)))
+ println(' return {};'.format(default))
+
+ with io.open('../irregexp/RegExpCharacters-inl.h', 'wb') as chars_file:
+ write = partial(print, file=chars_file, sep='', end='')
+ println = partial(write, end='\n')
+
+ write(warning_message)
+ write(unicode_version_message.format(version))
+
+ println('#ifndef V8_JSREGEXPCHARACTERS_INL_H_')
+ println('#define V8_JSREGEXPCHARACTERS_INL_H_')
+ println('')
+ println('namespace js {')
+ println('')
+ println('namespace irregexp {')
+ println('')
+
+ println('static inline bool')
+ println('RangeContainsLatin1Equivalents(CharacterRange range, bool unicode)')
+ println('{')
+ write_character_test(println, lambda ch: 'range.Contains({})'.format(hex4(ch)),
+ lambda _: 'true', 'false')
+ println('}')
+
+ println('')
+ println('} } // namespace js::irregexp')
+ println('')
+ println('#endif // V8_JSREGEXPCHARACTERS_INL_H_')
+
+ with io.open('../irregexp/RegExpCharacters.cpp', 'wb') as chars_file:
+ write = partial(print, file=chars_file, sep='', end='')
+ println = partial(write, end='\n')
+ character_range = partial(write_character_range, println)
+
+ # Characters in \s, 21.2.2.12 CharacterClassEscape.
+ space_chars = filter(is_space, xrange(0, MAX_BMP + 1))
+
+ # Characters in \d, 21.2.2.12 CharacterClassEscape.
+ digit_chars = map(ord, string.digits)
+ assert all(ch <= MAX_ASCII for ch in digit_chars)
+
+ # Characters in \w, 21.2.2.12 CharacterClassEscape.
+ word_chars = map(ord, string.digits + string.ascii_letters + '_')
+ assert all(ch <= MAX_ASCII for ch in word_chars)
+
+ # Characters which case-fold to characters in \w.
+ ignorecase_word_chars = (word_chars +
+ filter(casefolds_to_ascii, xrange(MAX_ASCII + 1, MAX_BMP + 1)))
+
+ # Surrogate characters.
+ surrogate_chars = range(LEAD_SURROGATE_MIN, TRAIL_SURROGATE_MAX + 1)
+
+ write(warning_message)
+ write(unicode_version_message.format(version))
+ println('#include "irregexp/RegExpCharacters.h"')
+ println('')
+ println('#include "mozilla/Assertions.h"')
+ println('')
+
+ println('char16_t')
+ println('js::irregexp::ConvertNonLatin1ToLatin1(char16_t c, bool unicode)')
+ println('{')
+ println(' MOZ_ASSERT(c > {}, "Character mustn\'t be Latin1");'.format(hex2(MAX_LATIN1)))
+ write_character_test(println, lambda ch: 'c == {}'.format(hex4(ch)), hex2, '0')
+ println('}')
+
+ character_range('Space', space_chars)
+ character_range('SpaceAndSurrogate', space_chars + surrogate_chars)
+
+ character_range('Word', word_chars)
+ character_range('IgnoreCaseWord', ignorecase_word_chars)
+ character_range('WordAndSurrogate', word_chars + surrogate_chars)
+ character_range('NegatedIgnoreCaseWordAndSurrogate',
+ set(xrange(0, MAX_BMP + 1)) - set(ignorecase_word_chars + surrogate_chars))
+
+ character_range('Digit', digit_chars)
+ character_range('DigitAndSurrogate', digit_chars + surrogate_chars)
+
+ character_range('Surrogate', surrogate_chars)
+
+ character_range('LineTerminator', line_terminator)
+
def update_unicode(args):
import urllib2
@@ -791,6 +1089,8 @@ def update_unicode(args):
table, index,
same_upper_table, same_upper_index,
non_bmp_lower_map, non_bmp_upper_map,
+ non_bmp_space_set,
+ non_bmp_id_start_set, non_bmp_id_cont_set,
test_table, test_space_table
) = process_unicode_data(unicode_data, derived_core_properties)
(
@@ -803,10 +1103,16 @@ def update_unicode(args):
make_unicode_file(unicode_version,
table, index,
same_upper_table, same_upper_index,
- folding_table, folding_index)
+ folding_table, folding_index,
+ non_bmp_space_set,
+ non_bmp_id_start_set, non_bmp_id_cont_set)
make_non_bmp_file(unicode_version,
non_bmp_lower_map, non_bmp_upper_map,
non_bmp_folding_map, non_bmp_rev_folding_map)
+ make_irregexp_tables(unicode_version,
+ table, index,
+ folding_table, folding_index,
+ test_table)
make_bmp_mapping_test(unicode_version, test_table)
make_non_bmp_mapping_test(unicode_version, non_bmp_upper_map, non_bmp_lower_map)