es-meta / esmeta

ECMAScript Specification (ECMA-262) Metalanguage
BSD 3-Clause "New" or "Revised" License
175 stars 12 forks source link

Refine object on property assignment #184

Closed hyp3rflow closed 10 months ago

hyp3rflow commented 11 months ago

This PR includes two changes below:

Each change makes diff in analysis:

Adds monkey-patching for BoundFunctionExoticObject

iter: 70,202 → 70,209 nodes: 16,307 → 16,313/20,020 (81.45% → 81.48%)

GetFunctionRealm: more analysis done

def GetFunctionRealm(
  obj: FunctionObject,
): Normal[RealmRecord] | Abrupt {
  if (! (= obj.Realm absent)) {
    return obj.Realm
  } else {}
  // before this change, FunctionObject is not related with BoundFunctionExoticObject
  // so this condition **was** evaluated as `Bot`, after fix, more analysis after this condition can be done.
  if (? obj: "BoundFunctionExoticObject") {
    let target = obj.BoundTargetFunction
    call %0 = clo<GetFunctionRealm>(target)
    return [? %0]
  } else {}
...

PrepareForOrdinaryCall: just state diff

def PrepareForOrdinaryCall(
  F: FunctionObject,
  newTarget: Object | Undefined,
): ExecutionContext {
  let callerContext = @EXECUTION_STACK[0]
  let calleeContext = (new ExecutionContext())
  calleeContext.Function = F
  // before this change, both two subtype of FunctionObject (ECMAScriptFunctionObject, BuiltinFunctionObject) all have `Realm` internal slot.
  // but BoundFunctionExoticObject doesn't have `Realm` internal slot and, in this fix, becomes subtype of `FunctionObject`.
  // so F.Realm is now evaluated as `RealmRecord | Absent`, which was `RealmRecord` only.
  let calleeRealm = F.Realm

Implements refining object on property assignment (diff with monkey-patched one)

error: 260 → 252 (-8) # of analyzed nodes are same.

Reduced errors

These errors are resolved as subtype refinement.

4,6d3
< [ParamTypeMismatch] argument assignment to first parameter _F_ when function call from OrdinaryFunctionCreate (step 22, 23:20-49) to SetFunctionLength <Call[4555]>
< - expected: FunctionObject
< - actual  : OrdinaryObject
658,660d654
< [ReturnTypeMismatch] return statement in ArrayCreate (step 7, 8:14-25) <Block[4797]>
< - expected: Normal[ArrayExoticObject] | Abrupt
< - actual  : Normal[Object]
673,675d666
< [ReturnTypeMismatch] return statement in BoundFunctionCreate (step 10, 12:14-27) <Block[4766]>
< - expected: Normal[FunctionObject] | Abrupt
< - actual  : Normal[Object]
685,687d675
< [ReturnTypeMismatch] return statement in CreateMappedArgumentsObject (step 22, 34:14-27) <Block[5021]>
< - expected: ArgumentsExoticObject
< - actual  : Object
733,735d720
< [ReturnTypeMismatch] return statement in IntegerIndexedObjectCreate (step 11, 12:14-25) <Block[5112]>
< - expected: IntegerIndexedExoticObject
< - actual  : Object
739,741d723
< [ReturnTypeMismatch] return statement in ModuleNamespaceCreate (step 10, 11:14-25) <Block[5218]>
< - expected: ModuleNamespaceExoticObject
< - actual  : Object
760,762d741
< [ReturnTypeMismatch] return statement in ProxyCreate (step 8, 12:12-23) <Block[5578]>
< - expected: Normal[ProxyExoticObject] | Abrupt
< - actual  : Normal[Object]
772,774d750
< [ReturnTypeMismatch] return statement in StringCreate (step 9, 10:14-25) <Block[4894]>
< - expected: StringExoticObject
< - actual  : Object

Return type and state changes in analysis

Total 27 changes in return type All of these changes seem valid, at least these are in subtype relations.

12c12
< -> def AddEntriesFromIterable(target: OrdinaryObject, iterable: Object | Symbol | Number | BigInt | String | Boolean, adder: FunctionObject): Normal[ESValue] | Abrupt
---
> -> def AddEntriesFromIterable(target: MapInstance | WeakMapInstance, iterable: Object | Symbol | Number | BigInt | String | Boolean, adder: FunctionObject): Normal[ESValue] | Abrupt
717c717
< -> def AsyncGeneratorStart(generator: OrdinaryObject, generatorBody: Ast[FunctionBody]): Const[~unused~]
---
> -> def AsyncGeneratorStart(generator: AsyncGeneratorInstance | GeneratorInstance, generatorBody: Ast[FunctionBody]): Const[~unused~]
1089c1089
< -> def BoundFunctionCreate(targetFunction: FunctionObject, boundThis: ESValue, boundArgs: List[ESValue]): Normal[FunctionObject]
---
> -> def BoundFunctionCreate(targetFunction: FunctionObject, boundThis: ESValue, boundArgs: List[ESValue]): Normal[BoundFunctionExoticObject]
1899c1899
< -> def CreateArrayIterator(array: Object, kind: Const[~key+value~, ~key~, ~value~]): OrdinaryObject
---
> -> def CreateArrayIterator(array: Object, kind: Const[~key+value~, ~key~, ~value~]): GeneratorInstance
1908c1908
< -> def CreateAsyncIteratorFromClosure(closure: Bot, generatorBrand: Bot, generatorPrototype: Object): OrdinaryObject
---
> -> def CreateAsyncIteratorFromClosure(closure: Bot, generatorBrand: Bot, generatorPrototype: Object): AsyncGeneratorInstance
1926c1926
< -> def CreateForInIterator(object: Object): OrdinaryObject
---
> -> def CreateForInIterator(object: Object): ForInIteratorInstance
1935c1935
< -> def CreateIteratorFromClosure(closure: Clo["CreateArrayIterator:clo0", "CreateListIteratorRecord:clo0", "CreateMapIterator:clo0", "CreateRegExpStringIterator:clo0", "CreateSetIterator:clo0", "INTRINSICS.String.prototype[@@iterator]:clo0"], generatorBrand: Const[~empty~] | String["%ArrayIteratorPrototype%", "%MapIteratorPrototype%", "%RegExpStringIteratorPrototype%", "%SetIteratorPrototype%", "%StringIteratorPrototype%"], generatorPrototype: Object): OrdinaryObject
---
> -> def CreateIteratorFromClosure(closure: Clo["CreateArrayIterator:clo0", "CreateListIteratorRecord:clo0", "CreateMapIterator:clo0", "CreateRegExpStringIterator:clo0", "CreateSetIterator:clo0", "INTRINSICS.String.prototype[@@iterator]:clo0"], generatorBrand: Const[~empty~] | String["%ArrayIteratorPrototype%", "%MapIteratorPrototype%", "%RegExpStringIteratorPrototype%", "%SetIteratorPrototype%", "%StringIteratorPrototype%"], generatorPrototype: Object): GeneratorInstance
1947c1947
< -> def CreateMapIterator(map: ESValue, kind: Const[~key+value~, ~key~, ~value~]): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def CreateMapIterator(map: ESValue, kind: Const[~key+value~, ~key~, ~value~]): Normal[GeneratorInstance] | Abrupt[throw]
1968c1968
< -> def CreateRegExpStringIterator(R: Object, S: String, global: Boolean, fullUnicode: Boolean): OrdinaryObject
---
> -> def CreateRegExpStringIterator(R: Object, S: String, global: Boolean, fullUnicode: Boolean): GeneratorInstance
1974c1974
< -> def CreateResolvingFunctions(promise: OrdinaryObject): Unknown["RecordWithFields[[Resolve]](aFunctionObject)And[[Reject]](aFunctionObject)"]
---
> -> def CreateResolvingFunctions(promise: PromiseInstance): Unknown["RecordWithFields[[Resolve]](aFunctionObject)And[[Reject]](aFunctionObject)"]
1977c1977
< -> def CreateSetIterator(set: ESValue, kind: Const[~key+value~, ~value~]): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def CreateSetIterator(set: ESValue, kind: Const[~key+value~, ~value~]): Normal[GeneratorInstance] | Abrupt[throw]
2205c2205
< -> def EnumerateObjectProperties(O: Object): OrdinaryObject
---
> -> def EnumerateObjectProperties(O: Object): ForInIteratorInstance
3429c3429
< -> def GeneratorStart(generator: OrdinaryObject, generatorBody: Clo["CreateArrayIterator:clo0", "CreateListIteratorRecord:clo0", "CreateMapIterator:clo0", "CreateRegExpStringIterator:clo0", "CreateSetIterator:clo0", "INTRINSICS.String.prototype[@@iterator]:clo0"] | Ast[FunctionBody]): Const[~unused~]
---
> -> def GeneratorStart(generator: AsyncGeneratorInstance | GeneratorInstance, generatorBody: Clo["CreateArrayIterator:clo0", "CreateListIteratorRecord:clo0", "CreateMapIterator:clo0", "CreateRegExpStringIterator:clo0", "CreateSetIterator:clo0", "INTRINSICS.String.prototype[@@iterator]:clo0"] | Ast[FunctionBody]): Const[~unused~]
3675c3675
< -> def <BUILTIN>:INTRINSICS.Array.prototype.entries(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.Array.prototype.entries(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]
3711c3711
< -> def <BUILTIN>:INTRINSICS.Array.prototype.keys(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.Array.prototype.keys(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]
3762c3762
< -> def <BUILTIN>:INTRINSICS.Array.prototype.values(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.Array.prototype.values(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]
3855c3855
< -> def <BUILTIN>:INTRINSICS.Boolean(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject | Boolean] | Abrupt
---
> -> def <BUILTIN>:INTRINSICS.Boolean(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[BooleanObject | Boolean] | Abrupt
4125c4125
< -> def <BUILTIN>:INTRINSICS.Map.prototype.entries(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.Map.prototype.entries(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]
4137c4137
< -> def <BUILTIN>:INTRINSICS.Map.prototype.keys(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.Map.prototype.keys(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]
4143c4143
< -> def <BUILTIN>:INTRINSICS.Map.prototype.values(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.Map.prototype.values(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]
4254c4254
< -> def <BUILTIN>:INTRINSICS.Number(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject | Number] | Abrupt
---
> -> def <BUILTIN>:INTRINSICS.Number(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[NumberObject | Number] | Abrupt
4527c4527
< -> def <BUILTIN>:INTRINSICS.Set.prototype.entries(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.Set.prototype.entries(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]
4536c4536
< -> def <BUILTIN>:INTRINSICS.Set.prototype.values(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.Set.prototype.values(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]
4653c4653
< -> def <BUILTIN>:INTRINSICS.String.prototype[@@iterator](this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt
---
> -> def <BUILTIN>:INTRINSICS.String.prototype[@@iterator](this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt
4707c4707
< -> def <BUILTIN>:INTRINSICS.TypedArray.prototype.entries(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.TypedArray.prototype.entries(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]
4737c4737
< -> def <BUILTIN>:INTRINSICS.TypedArray.prototype.keys(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.TypedArray.prototype.keys(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]
4773c4773
< -> def <BUILTIN>:INTRINSICS.TypedArray.prototype.values(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[OrdinaryObject] | Abrupt[throw]
---
> -> def <BUILTIN>:INTRINSICS.TypedArray.prototype.values(this: ESValue, ArgumentsList: List[ESValue], NewTarget: Object | Undefined): Normal[GeneratorInstance] | Abrupt[throw]