Skip to content

Commit

Permalink
Implemented PUT inline cache, optimized converter
Browse files Browse the repository at this point in the history
  • Loading branch information
fholm committed Apr 25, 2011
1 parent c47f0d5 commit 1a92c41
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 101 deletions.
2 changes: 1 addition & 1 deletion Src/IronJS/Compiler.Core.fs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ module Core =
//Objects
| Ast.Object properties -> Object.literalObject ctx properties
| Ast.Array indexes -> Object.literalArray ctx indexes
| Ast.Index(tree, index) -> Object.getIndex ctx tree index
| Ast.Index(tree, index) -> Object.getIndex_Ast ctx tree index
| Ast.Property(tree, name) -> Object.getMember_Ast ctx tree name false

//Functions
Expand Down
5 changes: 2 additions & 3 deletions Src/IronJS/Compiler.Identifier.fs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ module internal Identifier =
let dynamicArgs = getDynamicArgs ctx name
let args = defaultArgs @ dynamicArgs
Dlr.callStaticT<DynamicScopeHelpers> "Get" args

///
let private setValueDynamic (ctx:Ctx) name value =
let defaultArgs = [Dlr.const' name; Utils.box value; ctx.Parameters.DynamicScope :> Dlr.Expr]
Expand Down Expand Up @@ -76,8 +76,7 @@ module internal Identifier =
| _ ->
match ctx |> getVariableStorage name with
| None ->
let name = Dlr.const' name
Utils.tempBlock value (fun value -> [ctx.Globals |> Object.Property.put name value])
Object.putMember ctx ctx.Globals name value

| Some(expr, i, _) ->
let varExpr = (Dlr.indexInt expr i)
Expand Down
190 changes: 116 additions & 74 deletions Src/IronJS/Compiler.Object.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,85 +15,32 @@ module internal Object =

///
module Property =

///
let private makeInlineCache() =
let cache = !!!(new Runtime.Optimizations.InlinePropertyPutCache())
let cacheId = cache .-> "CachedId"
let cacheIndex = cache .-> "CachedIndex"
cache, cacheId, cacheIndex

///

//
let putBox expr name value =
let cache, cacheId, cacheIndex = makeInlineCache()

tempBlockT<CO> expr (fun tmp ->
[tempBlock value (fun valueTmp ->
let args = [expr; name; valueTmp]

[
Dlr.ternary
(cacheId .== (expr .-> "PropertySchema" .-> "Id"))
(Dlr.block [] [(Dlr.index (expr .-> "Properties") [cacheIndex] .-> "Value") .= valueTmp; Dlr.void'])
(call cache "Put" args)

valueTmp
]
let args = [name; valueTmp]
[call tmp "Put" args; valueTmp]
)]
)

///
let putRef expr name (value:Dlr.Expr) =
let cache, cacheId, cacheIndex = makeInlineCache()

//
let putRef expr name (value:Dlr.Expr) =
tempBlockT<CO> expr (fun tmp ->
[tempBlock value (fun valueTmp ->
let tag = valueTmp.Type |> TypeTag.OfType |> Dlr.const'
let args = [expr; name; valueTmp; tag]

[
Dlr.ternary
(cacheId .== (expr .-> "PropertySchema" .-> "Id"))
(Dlr.block [] [
Dlr.index (expr .-> "Properties") [cacheIndex] .-> "Value" .-> "Clr" .= valueTmp
Dlr.index (expr .-> "Properties") [cacheIndex] .-> "Value" .-> "Tag" .= tag
Dlr.index (expr .-> "Properties") [cacheIndex] .-> "HasValue" .= !!!true
Dlr.void'
])
(call cache "Put" args)

valueTmp
]
let args = [name; valueTmp; tag]
[call tmp "Put" args; valueTmp]
)]
)

///
let putVal expr name (value:Dlr.Expr) =
let cache, cacheId, cacheIndex = makeInlineCache()

//
let putVal expr name (value:Dlr.Expr) =
tempBlockT<CO> expr (fun tmp ->
[tempBlock value (fun valueTmp ->
let args = [expr; name; Utils.normalizeVal valueTmp]

let idx = Dlr.paramT<int> "~index"
let prp = Dlr.paramT<Descriptor array> "~properties"

[
Dlr.ternary
(cacheId .== (expr .-> "PropertySchema" .-> "Id"))

(Dlr.block [idx; prp] [
idx .= cacheIndex
prp .= (expr .-> "Properties")
Dlr.index prp [idx] .-> "Value" .-> "Number" .= (Utils.normalizeVal valueTmp)
Dlr.index prp [idx] .-> "HasValue" .= !!!true
Dlr.void'
])

(call cache "Put" args)

valueTmp
]
let args = [name; Utils.normalizeVal valueTmp]
[call tmp "Put" args; valueTmp]
)]
)

Expand All @@ -104,14 +51,6 @@ module internal Object =
| IsRef -> putRef expr name value
| IsVal -> putVal expr name value

///
let putName expr name (value:Dlr.Expr) =
let name = Dlr.const' name
match value with
| IsBox -> putBox expr name value
| IsRef -> putRef expr name value
| IsVal -> putVal expr name value

///
let get name expr =
tempBlockT<CO> expr (fun tmp ->
Expand Down Expand Up @@ -250,12 +189,115 @@ module internal Object =
(Dlr.assign tmp newExpr :: initExprs) @ [tmp] |> Seq.ofList
)

/// MemberExpression [ Expression ]
let getIndex (ctx:Ctx) object' index =
ensureObject ctx object'
(fun x -> Index.get x index)
(fun x ->
(Dlr.ternary
(Dlr.callStaticT<Object> "ReferenceEquals" [Dlr.castT<obj> x; Dlr.null'])
(Dlr.callGeneric ctx.Env "RaiseTypeError" [typeof<BV>] [!!!ErrorUtils.nextErrorId()])
(Utils.Constants.Boxed.undefined)
)
)

///
let getIndex_Ast (ctx:Ctx) (expr:Ast.Tree) (index:Ast.Tree) =
getIndex ctx (ctx |> compile expr) (ctx |> compile index)

/// MemberExpression . String = Expression
let putMember (ctx:Ctx) (expr:Dlr.Expr) (name:string) (value:Dlr.Expr) =

//
let makePropertyPutCache (env:Env) =
let cache = !!!(new Runtime.Optimizations.InlinePropertyPutCache())
let cacheId = cache .-> "CachedId"
let cacheIndex = cache .-> "CachedIndex"
cache, cacheId, cacheIndex

//
let fromJsObject (jsobj:Dlr.Expr) (name:string) (value:Dlr.Expr) (ctx:Ctx) =
let env = ctx.Target.Environment
let cache, cacheId, cacheIndex = env |> makePropertyPutCache

match name with
| "length" -> Property.put !!!name value jsobj
| _ ->
let index = Dlr.paramT<int> "~index"
let properties = Dlr.paramT<Descriptor array> "~properties"
let fallbackArgs =
match value with
| IsBox -> [|jsobj; !!!name; value|]
| IsVal -> [|jsobj; !!!name; value |> Utils.normalizeVal|]
| IsRef -> [|jsobj; !!!name; value; !!!TypeTag.OfType(value.Type)|]

Dlr.Fast.block [||] [|
Dlr.ifElse
(cacheId .== jsobj .-> "PropertySchema" .-> "Id")
(Dlr.Fast.block [|index; properties|] [|
properties .= jsobj .-> "Properties"
index .= cacheIndex
Utils.assign (Dlr.index properties [index] .-> "Value") value
|])
(Dlr.call cache "Put" fallbackArgs)
value
|]

//
let fromClrObject (clrobj:Dlr.Expr) (name:string) (value:Dlr.Expr) (ctx:Ctx) =
let env = ctx.Target.Environment
value

//
let fromJsValue (jsval:Dlr.Expr) (name:string) (value:Dlr.Expr) (ctx:Ctx) =
Dlr.Fast.block [||] [|value|]

//
let fromBox (expr:Dlr.Expr) (name:string) throw (ctx:Ctx) =
Dlr.ternary
(Utils.Box.isObject expr)
(fromJsObject (Utils.Box.unboxObject expr) name throw ctx)
(Dlr.ternary
(Utils.Box.isClr expr)
(fromClrObject (Utils.Box.unboxClr expr) name value ctx)
(fromJsValue expr name value ctx)
)

let body = new Dlr.ExprList(3)
let vars = new Dlr.ParameterList(2)
let expr = expr |> Utils.toStatic vars body
let value = value |> Utils.toStatic vars body

match TypeTag.OfType(expr.Type) with
| TypeTags.Box ->
body.Add(fromBox expr name value ctx)

| TypeTags.Object
| TypeTags.Function ->
body.Add(fromJsObject expr name value ctx)

| TypeTags.String
| TypeTags.SuffixString
| TypeTags.Undefined
| TypeTags.Bool
| TypeTags.Number ->
body.Add(fromJsValue expr name value ctx)

| TypeTags.Clr ->
body.Add(fromClrObject expr name value ctx)

Dlr.block vars body

///
let putMember_Ast (ctx:Ctx) (ast:Ast.Tree) (name:string) (value:Ast.Tree) =
putMember ctx (ctx |> compile ast) name (ctx |> compile value)

///
let getMember (ctx:Ctx) (expr:Dlr.Expr) (name:string) (throwOnMissing:bool) =

//
let makePropertyGetCache (throwOnMissing:bool) (env:Env) =
let cache = !!!Runtime.Optimizations.InlinePropertyGetCache(env, throwOnMissing)
let cache = !!!(new Runtime.Optimizations.InlinePropertyGetCache(env, throwOnMissing))
let cacheId = cache .-> "CachedId"
let cacheIndex = cache .-> "CachedIndex"
cache, cacheId, cacheIndex
Expand Down
9 changes: 2 additions & 7 deletions Src/IronJS/Compiler.Operators.fs
Original file line number Diff line number Diff line change
Expand Up @@ -415,12 +415,7 @@ module internal Binary =

//Property assignment: foo.bar = 1;
| Ast.Property(object', name) ->
Utils.tempBlock value (fun value ->
let object' = object' |> ctx.Compile
let ifObj = Object.Property.put !!!name value
let ifClr _ = value
[Utils.ensureObject ctx object' ifObj ifClr]
)
Object.putMember ctx (object' |> ctx.Compile) name value

//Index assignemnt: foo[0] = "bar";
| Ast.Index(object', index) ->
Expand All @@ -445,7 +440,7 @@ module internal Binary =

Dlr.block [tmp] [
tmp .= idx
assign ctx ltree (Ast.Binary(op, ltree,rtree))
assign ctx ltree (Ast.Binary(op, ltree, rtree))
]

| _ ->
Expand Down
49 changes: 49 additions & 0 deletions Src/IronJS/Compiler.Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,55 @@ module internal Utils =
| Ast.Number n when TC.TryToIndex(n, &index) -> !!!index
| Ast.String s when TC.TryToIndex(s, &index) -> !!!index
| _ -> ctx.Compile indexAst

///
let toStatic (vars:Dlr.ParameterList) (body:Dlr.ExprList) (expr:Dlr.Expr) =
if expr |> Dlr.isStatic then
expr

else
let temp = Dlr.tempFor expr
vars.Add(temp)
body.Add(temp .= expr)
temp :> Dlr.Expr

///
module internal Convert =

///
let private convert (expr:Dlr.Expr) test unbox fallback =
match TypeTag.OfType(expr.Type) with
| TypeTags.Box ->
let body = new Dlr.ExprList(2)
let vars = new Dlr.ParameterList(1)
let expr = expr |> toStatic vars body

body.Add(
Dlr.ternary
(test expr)
(unbox expr)
(fallback())
)

if body.Count = 1 && vars.Count = 0
then body.[0]
else Dlr.block vars body

| _ ->
fallback()

///
let toNumber (expr:Dlr.Expr) =
let fallback () = Dlr.callStaticT<TC> "ToNumber" [expr]
//convert expr Box.isNumber Box.unboxNumber fallback
Dlr.callStaticT<TC> "ToNumber" [expr]

///
let toObject (ctx:Ctx) (expr:Dlr.Expr) =
let fallback () = Dlr.callStaticT<TC> "ToObject" [ctx.Env; expr]
//convert expr Box.isObject Box.unboxObject fallback
Dlr.callStaticT<TC> "ToObject" [ctx.Env; expr]


///
let ensureObject (ctx:Ctx) (expr:Dlr.Expr) ifObj ifClr =
Expand Down
2 changes: 1 addition & 1 deletion Src/IronJS/IronJS.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
<Compile Include="Caches.fs" />
<Compile Include="Runtime.fs" />
<Compile Include="Runtime.Binders.fs" />
<Compile Include="Core.Helpers.fs" />
<Compile Include="Helpers.fs" />
<Compile Include="Operators.fs" />
<Compile Include="InlineCaches.fs" />
<Compile Include="ReflectionCache.fs" />
Expand Down
Loading

0 comments on commit 1a92c41

Please sign in to comment.