Bug 147133

Summary: Add availability for InternalFunction to have JS implementation
Product: WebKit Reporter: Yusuke Suzuki <ysuzuki>
Component: JavaScriptCoreAssignee: Yusuke Suzuki <ysuzuki>
Status: NEW ---    
Severity: Normal CC: oliver, saam, sam
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on: 147183    
Bug Blocks:    

Description Yusuke Suzuki 2015-07-20 17:40:09 PDT
Current Promise constructor is implemented as an InternalFunction which has C++ implementations.
But almost all processes are done in JS builtin's @initializePromise function.
And after issue 147051 is landed, we can write the whole Promise constructor code in JS.

I suggest enabling InternalFunction to have JS function implementation instead of just replacing Promise constructor with a Promise builtin JS function object because if we replace the current Promise constructor with the JS function simply, we cannot leverage the getStaticFunctionSlot (& its system for materializing builtin functions lazily)
Comment 1 Yusuke Suzuki 2015-07-22 17:54:53 PDT
One problem is that, when just using the JS implemented Promise, the class info of the generated Promise becomes the usual JSFinalObject's info.
If we would like not to break the current

jsDynamicCast<JSPromise*>(promise)

and

promise.inherits(JSPromise::info())

We need to notify the class info into the ObjectAllocationProfile.
And at that time, we need to take care for DFG because DFG assumes that CreateThis results is always JSFinalObject.
Comment 2 Yusuke Suzuki 2015-07-24 18:18:33 PDT
After considering the design, I think introducing a byte code that changes class info is better. This byte code can be emitted only within the builtin code. And it occurs structure transitions due to the class info change.

I'm planning the following form.

constructor Promise(executor) {
    @classInfoTransition(this, "Promise");
    ...

}

This will keep the classInfo = JSPromise::info and `jsDynamicCast<JSPromise*>(promise)` in C++ working. It's useful for C++ users.
One thing we need to take care is that the C++ class should not extend the fields from the JSFinalObject.

Changing / notifying the base class info to ObjectAllocationProfile in the derived function constructor is a little bit difficult I think. In the almost all cases, super() chain is the static. However, seeing the spec, I've found

    Reflect.construct ( target, argumentsList [, newTarget] )
    // http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.construct

can specify the newTarget even if the target is not related to the newTarget completely.
Comment 3 Yusuke Suzuki 2015-10-17 16:27:39 PDT
The problematic part is, DFG assumes that classInfo won't be changed.
For example, in the clobberize phase, we rely on the fact that classInfo won't be changed through transitions.