Closed
Bug 1120168
Opened 10 years ago
Closed 10 years ago
Assertion failure at jspropertytree.cpp when using JS_SELF_HOSTED_* macros in RegExp.cpp
Categories
(Core :: JavaScript Engine, defect)
Core
JavaScript Engine
Tracking
()
RESOLVED
FIXED
mozilla38
Tracking | Status | |
---|---|---|
firefox38 | --- | fixed |
People
(Reporter: 446240525, Unassigned)
References
Details
Attachments
(2 files, 2 obsolete files)
827 bytes,
text/x-patch
|
Details | |
16.66 KB,
patch
|
till
:
review+
|
Details | Diff | Splinter Review |
I got this failure when I tried to self-host RegExp.prototype.flags:
!parent->inDictionary(), at /spidermonkey/js/src/jspropertytree.cpp:51
Comment 1•10 years ago
|
||
The problem is following:
1. Intl.js uses RegExp literals
RegExp class is initialilzed before Self-hosting global is initialized.
2. Intl.js calls RegExp constructor while initialization
Almost same as 1, and it requires `RegExp` name defined in Self-hosting global.
3. We're goint to make RegExp.prototype property self-hosted
Initializing RegExp class requires Self-hosting global to be initialized before it.
I guess possible solution would be one of following:
A. Lazify initialization of RegExp instances in Intl.js
B. Do not use RegExp in Self-hosted JS
and I'm trying to implement A.
Comment 2•10 years ago
|
||
Draft patch is here.
It works without any errors
https://treeherder.mozilla.org/#/jobs?repo=try&revision=6100afe979b9
but it would be nice to cache RegExp instances, or at least generated pattern strings (languageTag, etc) to avoid performance regression. There are some limitations now:
1. Cannot set intrinsic variable after initialization
I cannot store RegExp instance into global variable.
https://hg.mozilla.org/mozilla-central/file/2cb22c058add/js/src/vm/GlobalObject.h#l586> bool setIntrinsicValue(JSContext *cx, PropertyName *name, HandleValue value) {
> #ifdef DEBUG
> RootedObject self(cx, this);
> MOZ_ASSERT(cx->runtime()->isSelfHostingGlobal(self));
> #endif
2. Cannot store non flat string in intrinsic variable
I cannot store generated pattern strings into global variable.
https://hg.mozilla.org/mozilla-central/file/2cb22c058add/js/src/vm/SelfHosting.cpp#l1332
> } else if (selfHostedValue.isString()) {
> if (!selfHostedValue.toString()->isFlat())
> MOZ_CRASH();
What would be the best way to cache them?
Attachment #8562842 -
Flags: feedback?(till)
Comment 3•10 years ago
|
||
Hey, just quickly wanted to tell you that it'll be a few days until I get to reviewing this.
Comment 4•10 years ago
|
||
Comment on attachment 8562842 [details] [diff] [review]
Do not use RegExp literal and do not call RegExp constructor before self-hosting global is initialized in Intl.js.
Review of attachment 8562842 [details] [diff] [review]:
-----------------------------------------------------------------
This looks pretty good already. I agree with you regarding the performance concerns, though, so we should solve those.
What you can do is encapsulating all the Intl regexps in a holder object that you create during self-hosting initialization. On that, you can create properties as in normal code:
var internalIntlRegExps = std_Object_create(null);
function getUnicodeLocaleExtensionSequenceRE() {
return internalIntlRegExps.unicodeLocaleExtensionSequenceRE || (internalIntlRegExps.unicodeLocaleExtensionSequenceRE = regexp_construct(unicodeLocaleExtensionSequence));
}
(Obviously with proper line-wrapping and all that. Also, I would just inline the unicodeLocaleExtensionSequence string instead of having it in its own var.)
::: js/src/builtin/RegExp.h
@@ +80,5 @@
> extern bool
> regexp_test_no_statics(JSContext *cx, unsigned argc, Value *vp);
>
> +/*
> + * Implementation of RegExp constructor.
While in line with the comments for the two functions above, I'm not too happy with this comment. If I'd encounter it without thinking about self-hosting, I'd be very confused by it.
Perhaps something like "RegExp constructor function, used for the normal RegExp builtin and as a callable that returns a bare, prototype-less RegExp instance in self-hosting."
Attachment #8562842 -
Flags: feedback?(till) → feedback+
Comment 5•10 years ago
|
||
Thank you for your feedback!
(In reply to Till Schneidereit [:till] from comment #4)
> Comment on attachment 8562842 [details] [diff] [review]
> Do not use RegExp literal and do not call RegExp constructor before
> self-hosting global is initialized in Intl.js.
>
> Review of attachment 8562842 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> This looks pretty good already. I agree with you regarding the performance
> concerns, though, so we should solve those.
>
> What you can do is encapsulating all the Intl regexps in a holder object
> that you create during self-hosting initialization. On that, you can create
> properties as in normal code:
>
> var internalIntlRegExps = std_Object_create(null);
> function getUnicodeLocaleExtensionSequenceRE() {
> return internalIntlRegExps.unicodeLocaleExtensionSequenceRE ||
> (internalIntlRegExps.unicodeLocaleExtensionSequenceRE =
> regexp_construct(unicodeLocaleExtensionSequence));
> }
>
> (Obviously with proper line-wrapping and all that. Also, I would just inline
> the unicodeLocaleExtensionSequence string instead of having it in its own
> var.)
Okay, thanks.
I guess it's better to create properties with undefined (or null?) in top-level code (maybe just after std_Object_create), and get/set the property in get*RE functions, to avoid "reference to undefined property" warning, right?
Or perhaps the warning does not matter?
> ::: js/src/builtin/RegExp.h
> @@ +80,5 @@
> > extern bool
> > regexp_test_no_statics(JSContext *cx, unsigned argc, Value *vp);
> >
> > +/*
> > + * Implementation of RegExp constructor.
>
> While in line with the comments for the two functions above, I'm not too
> happy with this comment. If I'd encounter it without thinking about
> self-hosting, I'd be very confused by it.
>
> Perhaps something like "RegExp constructor function, used for the normal
> RegExp builtin and as a callable that returns a bare, prototype-less RegExp
> instance in self-hosting."
What does "a bare, prototype-less RegExp instance" mean here?
regexp_construct function returns normal RegExp instance, which has a prototype.
Flags: needinfo?(till)
Comment 6•10 years ago
|
||
(In reply to Tooru Fujisawa [:arai] from comment #5)
> Okay, thanks.
> I guess it's better to create properties with undefined (or null?) in
> top-level code (maybe just after std_Object_create), and get/set the
> property in get*RE functions, to avoid "reference to undefined property"
> warning, right?
> Or perhaps the warning does not matter?
Blech, I hate that warning. :(
And yes, what you propose is the right way to work around it.
> What does "a bare, prototype-less RegExp instance" mean here?
> regexp_construct function returns normal RegExp instance, which has a
> prototype.
It does? Hmm, probably because regexps are somewhere between objects and primitives :/ Anyway, I'm pretty sure it doesn't matter here because of the way we use the regexps.
It does, however, mean that my comment change request is pretty bogus, so just ignore it.
Flags: needinfo?(till)
Comment 7•10 years ago
|
||
Thank you again, I updated the patch.
Almost green on try run: https://treeherder.mozilla.org/#/jobs?repo=try&revision=36cec14d0fda
(one crash in devtools, but I guess it's not related to this patch)
Attachment #8562842 -
Attachment is obsolete: true
Attachment #8566248 -
Flags: review?(till)
Comment 8•10 years ago
|
||
Does calling regexp_construct work even if `RegExp.multiline` is set? IOW a regexp_construct_no_statics method is not required?
Comment 9•10 years ago
|
||
(In reply to André Bargull from comment #8)
> Does calling regexp_construct work even if `RegExp.multiline` is set? IOW a
> regexp_construct_no_statics method is not required?
Excellent question. Arai, can you verify that/if things work with `RegExp.multiline = true`? If not, please adapt things to a regexp_construct_no_statics. If yes, r=me on the patch.
Comment 10•10 years ago
|
||
(In reply to Till Schneidereit [:till] from comment #9)
> (In reply to André Bargull from comment #8)
> > Does calling regexp_construct work even if `RegExp.multiline` is set? IOW a
> > regexp_construct_no_statics method is not required?
>
> Excellent question. Arai, can you verify that/if things work with
> `RegExp.multiline = true`? If not, please adapt things to a
> regexp_construct_no_statics. If yes, r=me on the patch.
Thank you André for pointing that out :)
It doesn't work correctly, and I replaced it with regexp_construct_no_statics.
Green on try run: https://treeherder.mozilla.org/#/jobs?repo=try&revision=b741baa0f46e
Attachment #8566248 -
Attachment is obsolete: true
Attachment #8566248 -
Flags: review?(till)
Attachment #8566920 -
Flags: review?(till)
Comment 11•10 years ago
|
||
Comment on attachment 8566920 [details] [diff] [review]
Do not use RegExp literal and do not call RegExp constructor before self-hosting global is initialized in Intl.js.
Review of attachment 8566920 [details] [diff] [review]:
-----------------------------------------------------------------
Thanks, this is top-notch work!
::: js/src/builtin/RegExp.cpp
@@ +269,5 @@
> CallArgs args = CallArgsFromVp(argc, vp);
> return CallNonGenericMethod<IsRegExp, regexp_compile_impl>(cx, args);
> }
>
> +bool
Please make this static again.
Attachment #8566920 -
Flags: review?(till) → review+
Comment 12•10 years ago
|
||
Status: NEW → RESOLVED
Closed: 10 years ago
status-firefox38:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla38
You need to log in
before you can comment on or make changes to this bug.
Description
•