[webkit-dev] JavascriptCore questions

Geoffrey Garen ggaren at apple.com
Tue Dec 19 16:44:31 PST 2006


Hi Ed.

> Interpreters, ExecStates, Binding
> ---------------------------------
> - ConvertValueToNPVariant() and convertValueToObjcValue(), which are
> used in the plugin interface binding code, both contain special logic
> that basically says "if wrapping up a window object, store the
> RootObject associated with the window object in the wrapper rather  
> than
> the current RootObject". Can you tell me the purpose of this logic? I
> have theories, but nothing definitive.

I'm not sure.

> - The JavaScriptObject struct contains pointers to RootObjects. I  
> may be
> missing something, but it appears to me that a JavaScriptObject struct
> can outlive the RootObjects that it points at, which could lead to the
> use of freed memory. Can this happen?

Yes, I think so. That's a bug. We're tracking some bugs along those  
lines.

> - What are the rules around exceptions in the ExecState retrieved from
> Interpreter::globalExec()? It appears that most of the uses of it  
> assume
> that there is no exception already in the ExecState when it is  
> retrieved
> and clear any exception and before returning ensure that it  
> contains no
> exception. Is this correct?

It is an error to leave an ExecState in an exceptional state when  
you're done executing, because your leftover exception will 'throw'  
in the next script that tries to execute.

Historically, the ExecState was used to store exception data because  
it got passed to most functions, so it was convenient. Unfortunately,  
this design clouded understanding of which functions could throw and  
which couldn't. In Nodes.cpp, you'll notice that we have macros that  
attempt to clean up after this design, retrieving exception data and  
putting it in the right place (KJS_CHECKEXCEPTION, etc.). But in the  
API, we use exception out parameters instead, for clarity.

> - When a plugin is unloaded, what happens if there are existing
> RuntimeObjectImp instances that reference objects provided by the
> plugin? Is there logic to prevent a plugin from being unloaded if  
> there
> are extant objects that it has provided? I haven't been able to  
> find any
> code that ensures this.

No. I believe this is a bug.

> - There are a variety of places where
> exec->dynamicInterpreter()->globalObject() is called. For example,  
> this
> happens in FunctionProtoFunc::callAsFunction() to handle the apply  
> case
> when the this arg is NULL. In such cases, is it correct to use the
> global obj from the current ExecState's Interpreter as opposed to the
> global object at the root of the scope chain? ECMA 262 section  
> 15.3.4.4
> seems somewhat ambiguous on this subject, but my reading leads me to
> think that it would be more correct to pull from the scope chain.

Filed as http://bugs.webkit.org/show_bug.cgi?id=11884.

> JSObject and JSValue
> --------------------
> - Can you confirm that NULL is never an immediate JSValue and can be
> used to mean "no JSValue"?

Yes. That's a documented property of our API Inside the engine, we  
never use a NULL JSValues, and only use JavaScript values like  
jsUndefined() and jsNull().

> - Is it legal for JSObject::hasProperty(), JSObject::canPut(), or
> JSObject::deleteProperty()  to set an exception in the passed  
> ExecState?
> I cannot find any current code doing this, but I'm not sure if it is a
> case I need to handle or not.

deleteProperty can set an exception; hasProperty and canPut can't.

> - Is it legal for JSObject::get() to ever return NULL?  I cannot find
> any current code doing this, but I'm not sure if it is a case I  
> need to
> handle or not.

JSObject::get can only return a JSValue or undefined. That's  
documented in the ECMA spec.

> - Is it legal to set an exception in the passed ExecState in
> PropertySlot's GetValueFunc? I can't find any precedent in the code  
> for
> a propgetter (or get itself for that matter) to throw.

A getter function can throw like any other function, so there is  
general precedent for throwing from "get." No GetValueFuncs that I  
can think of throw, but it doesn't seem out of the question to write  
one that would.

> - Is it legal for JSObject::call() to ever return NULL?  I cannot find
> any current code doing this, but I'm not sure if it is a case I  
> need to
> handle or not.

No. JSObject::call, like any evaluation, must return a valid JSValue.

> - Is the result of JSValue::type() expected to be immutable for a  
> given
> JSValue instance? That is, can a particular instance return different
> types at different times?

type() can be mutable. See ObjcFallbackObjectImp::type() for a  
particularly bad use of this idiom. Generally, we use type() to  
validate type casts.

> - Are the results of JSObject::implementsConstruct(),
> JSObject::implementsCall(), and JSObject::implementsHasInstance()
> expected to be immutable for a given JSObject instance? That is, can a
> particular instance return different values at different times?

Ditto.

> - The default implementation of JSObject::defaultValue() and
> JSObject::toPrimitive() can return an Error object if an exception
> occurs. This would seem to violate ECMA 262 sections 8.6.2.6 and 9.1
> which state that defaultvalue() and toPrimitive() return non-Object
> types. Looking at some of the callers of toPrimitive(), it appears  
> that
> some are not prepared to handle getting an object back. I'll file this
> as a bug if you guys like.

defaultValue() and toPrimitive() must be able to throw exceptions  
because they call arbitrary functions. When the spec says, "The above  
specification of [[DefaultValue]] for native objects can return only  
primitive values," I think it's just attempting to explain that the  
purpose of defaultValue() is to return a primitive value, although it  
can throw an exception as well. If there's code that might fail  
because an exception is thrown, I think that warrants a bug.

> - Neither JSObject::propertyIsEnumerable() nor
> JSObject::getPropertyAttributes() are virtual, making it impossible  
> for
> a subclass to override the default behavior. Any objection to making
> propertyIsEnumerable() virtual, and making getPropertyAttributes()
> private?

If you want to override those functions, you're probably (although  
not definitely) doing things wrong. Object has default behavior,  
allowing you to add and remove properties with attributes. Subclasses  
can implement custom properties, overriding get, put,  
getPropertyNames, etc. So there's no need to muck around in Object's  
implementation of its default behavior, when you can override that  
behavior, instead. In other words, the functions you mention should  
really be private, instead of virtual.

Hope that helps.

Geoff






More information about the webkit-dev mailing list