Skip to content

Commit

Permalink
Support constructor type
Browse files Browse the repository at this point in the history
  • Loading branch information
jhnaldo committed Oct 8, 2024
1 parent 24c7181 commit de9ef68
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 84 deletions.
25 changes: 12 additions & 13 deletions src/main/resources/manuals/funcs/INTRINSICS.EvalError.ir
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
def <BUILTIN>:INTRINSICS.EvalError(
this: ESValue,
ArgumentsList: List[ESValue],
NewTarget: Object | Undefined,
NewTarget: Constructor | Undefined,
): Unknown {
if (< 0 ArgumentsList.length) let message = (pop < ArgumentsList) else let message = absent
if (< 0 ArgumentsList.length) let options = (pop < ArgumentsList) else let options = absent
%0 = (= NewTarget undefined)
if %0 {
if (= NewTarget undefined) {
let newTarget = @EXECUTION_STACK[0].Function
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%EvalError.prototype%", (new ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
call %3 = clo<ToString>(message)
let msg = [? %3]
call %4 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %4]
call %0 = clo<OrdinaryCreateFromConstructor>(newTarget, "%EvalError.prototype%", (new ["ErrorData"]))
let O = [? %0]
%1 = (! (= message undefined))
if %1 {
call %2 = clo<ToString>(message)
let msg = [? %2]
call %3 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %3]
} else {}
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
call %4 = clo<InstallErrorCause>(O, options)
[? %4]
return O
}
25 changes: 12 additions & 13 deletions src/main/resources/manuals/funcs/INTRINSICS.RangeError.ir
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
def <BUILTIN>:INTRINSICS.RangeError(
this: ESValue,
ArgumentsList: List[ESValue],
NewTarget: Object | Undefined,
NewTarget: Constructor | Undefined,
): Unknown {
if (< 0 ArgumentsList.length) let message = (pop < ArgumentsList) else let message = absent
if (< 0 ArgumentsList.length) let options = (pop < ArgumentsList) else let options = absent
%0 = (= NewTarget undefined)
if %0 {
if (= NewTarget undefined) {
let newTarget = @EXECUTION_STACK[0].Function
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%RangeError.prototype%", (new ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
call %3 = clo<ToString>(message)
let msg = [? %3]
call %4 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %4]
call %0 = clo<OrdinaryCreateFromConstructor>(newTarget, "%RangeError.prototype%", (new ["ErrorData"]))
let O = [? %0]
%1 = (! (= message undefined))
if %1 {
call %2 = clo<ToString>(message)
let msg = [? %2]
call %3 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %3]
} else {}
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
call %4 = clo<InstallErrorCause>(O, options)
[? %4]
return O
}
25 changes: 12 additions & 13 deletions src/main/resources/manuals/funcs/INTRINSICS.ReferenceError.ir
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
def <BUILTIN>:INTRINSICS.ReferenceError(
this: ESValue,
ArgumentsList: List[ESValue],
NewTarget: Object | Undefined,
NewTarget: Constructor | Undefined,
): Unknown {
if (< 0 ArgumentsList.length) let message = (pop < ArgumentsList) else let message = absent
if (< 0 ArgumentsList.length) let options = (pop < ArgumentsList) else let options = absent
%0 = (= NewTarget undefined)
if %0 {
if (= NewTarget undefined) {
let newTarget = @EXECUTION_STACK[0].Function
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%ReferenceError.prototype%", (new ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
call %3 = clo<ToString>(message)
let msg = [? %3]
call %4 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %4]
call %0 = clo<OrdinaryCreateFromConstructor>(newTarget, "%ReferenceError.prototype%", (new ["ErrorData"]))
let O = [? %0]
%1 = (! (= message undefined))
if %1 {
call %2 = clo<ToString>(message)
let msg = [? %2]
call %3 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %3]
} else {}
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
call %4 = clo<InstallErrorCause>(O, options)
[? %4]
return O
}
25 changes: 12 additions & 13 deletions src/main/resources/manuals/funcs/INTRINSICS.SyntaxError.ir
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
def <BUILTIN>:INTRINSICS.SyntaxError(
this: ESValue,
ArgumentsList: List[ESValue],
NewTarget: Object | Undefined,
NewTarget: Constructor | Undefined,
): Unknown {
if (< 0 ArgumentsList.length) let message = (pop < ArgumentsList) else let message = absent
if (< 0 ArgumentsList.length) let options = (pop < ArgumentsList) else let options = absent
%0 = (= NewTarget undefined)
if %0 {
if (= NewTarget undefined) {
let newTarget = @EXECUTION_STACK[0].Function
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%SyntaxError.prototype%", (new ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
call %3 = clo<ToString>(message)
let msg = [? %3]
call %4 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %4]
call %0 = clo<OrdinaryCreateFromConstructor>(newTarget, "%SyntaxError.prototype%", (new ["ErrorData"]))
let O = [? %0]
%1 = (! (= message undefined))
if %1 {
call %2 = clo<ToString>(message)
let msg = [? %2]
call %3 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %3]
} else {}
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
call %4 = clo<InstallErrorCause>(O, options)
[? %4]
return O
}
25 changes: 12 additions & 13 deletions src/main/resources/manuals/funcs/INTRINSICS.TypeError.ir
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
def <BUILTIN>:INTRINSICS.TypeError(
this: ESValue,
ArgumentsList: List[ESValue],
NewTarget: Object | Undefined,
NewTarget: Constructor | Undefined,
): Unknown {
if (< 0 ArgumentsList.length) let message = (pop < ArgumentsList) else let message = absent
if (< 0 ArgumentsList.length) let options = (pop < ArgumentsList) else let options = absent
%0 = (= NewTarget undefined)
if %0 {
if (= NewTarget undefined) {
let newTarget = @EXECUTION_STACK[0].Function
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%TypeError.prototype%", (new ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
call %3 = clo<ToString>(message)
let msg = [? %3]
call %4 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %4]
call %0 = clo<OrdinaryCreateFromConstructor>(newTarget, "%TypeError.prototype%", (new ["ErrorData"]))
let O = [? %0]
%1 = (! (= message undefined))
if %1 {
call %2 = clo<ToString>(message)
let msg = [? %2]
call %3 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %3]
} else {}
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
call %4 = clo<InstallErrorCause>(O, options)
[? %4]
return O
}
25 changes: 12 additions & 13 deletions src/main/resources/manuals/funcs/INTRINSICS.URIError.ir
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
def <BUILTIN>:INTRINSICS.URIError(
this: ESValue,
ArgumentsList: List[ESValue],
NewTarget: Object | Undefined,
NewTarget: Constructor | Undefined,
): Unknown {
if (< 0 ArgumentsList.length) let message = (pop < ArgumentsList) else let message = absent
if (< 0 ArgumentsList.length) let options = (pop < ArgumentsList) else let options = absent
%0 = (= NewTarget undefined)
if %0 {
if (= NewTarget undefined) {
let newTarget = @EXECUTION_STACK[0].Function
} else {
let newTarget = NewTarget
}
call %1 = clo<OrdinaryCreateFromConstructor>(newTarget, "%URIError.prototype%", (new ["ErrorData"]))
let O = [? %1]
%2 = (! (= message undefined))
if %2 {
call %3 = clo<ToString>(message)
let msg = [? %3]
call %4 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %4]
call %0 = clo<OrdinaryCreateFromConstructor>(newTarget, "%URIError.prototype%", (new ["ErrorData"]))
let O = [? %0]
%1 = (! (= message undefined))
if %1 {
call %2 = clo<ToString>(message)
let msg = [? %2]
call %3 = clo<CreateNonEnumerableDataPropertyOrThrow>(O, "message", msg)
[! %3]
} else {}
call %5 = clo<InstallErrorCause>(O, options)
[? %5]
call %4 = clo<InstallErrorCause>(O, options)
[? %4]
return O
}
4 changes: 3 additions & 1 deletion src/main/resources/manuals/tycheck-ignore.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"LengthOfArrayLike",
"MethodDefinition[0,0].DefineMethod",
"ModuleNamespaceCreate",
"OrdinaryCreateFromConstructor",
"OrdinaryFunctionCreate",
"ProxyCreate",
"SerializeJSONObject",
Expand All @@ -48,5 +49,6 @@
"Statement[1,0].LabelledEvaluation",
"Statement[2,0].LabelledEvaluation",
"StringCreate",
"ToIndex"
"ToIndex",
"TypedArrayCreate"
]
8 changes: 4 additions & 4 deletions src/main/resources/result/spec-summary
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
- algorithm steps: 19535 (96.80%)
- complete: 18909
- incomplete: 626
- types: 6999 (93.28%)
- known: 6529
- yet: 470
- types: 6999 (93.60%)
- known: 6551
- yet: 448
- unknown: 620
- tables: 89
- type model: 58
- type model: 59
14 changes: 14 additions & 0 deletions src/main/scala/esmeta/analyzer/TypeAnalyzer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ class TypeAnalyzer(
/** loading monads */
import AbsState.monad.*

/** transfer function for expressions */
override def transfer(expr: Expr)(using
cp: ControlPoint,
): Result[AbsValue] = expr match
// a precise type of `the active function object` in built-in functions
case ERef(
Prop(
Prop(Global("EXECUTION_STACK"), EMath(0)),
EStr("Function"),
),
) if cp.func.isBuiltin =>
pure(AbsValue(ConstructorT))
case _ => super.transfer(expr)

/** return-if-abrupt completion */
override def returnIfAbrupt(
riaExpr: EReturnIfAbrupt,
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/esmeta/spec/Head.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ sealed trait Head extends SpecElem {
List(
Param(ir.THIS_STR, Type(ESValueT)),
Param(ir.ARGS_LIST_STR, Type(ListT(ESValueT))),
Param(ir.NEW_TARGET_STR, Type(ObjectT || UndefT)),
Param(ir.NEW_TARGET_STR, Type(ConstructorT || UndefT)),
)

/** get function name */
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/esmeta/ty/TyModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ object TyModel {
"FunctionObject" -> TyInfo(
parent = Some("OrdinaryObject"),
),
"Constructor" -> TyInfo(
parent = Some("FunctionObject"),
),
"ECMAScriptFunctionObject" -> TyInfo(
parent = Some("FunctionObject"),
methods = Map(
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/esmeta/ty/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ def NameT(names: String*): ValueTy =
if (names.isEmpty) ValueTy.Bot
else ValueTy(name = NameTy(Fin(names.toSet)))
lazy val ObjectT: ValueTy = NameT("Object")
lazy val FunctionT: ValueTy = NameT("FunctionObject")
lazy val ConstructorT: ValueTy = NameT("Constructor")
lazy val ESPrimT: ValueTy = ValueTy(
symbol = true,
number = NumberTy.Top,
Expand Down

0 comments on commit de9ef68

Please sign in to comment.