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
_______________________________________________
webkit-dev mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-dev