cmpl_evaluate.go 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package otto
  2. import (
  3. "strconv"
  4. )
  5. func (self *_runtime) cmpl_evaluate_nodeProgram(node *_nodeProgram, eval bool) Value {
  6. if !eval {
  7. self.enterGlobalScope()
  8. defer func() {
  9. self.leaveScope()
  10. }()
  11. }
  12. self.cmpl_functionDeclaration(node.functionList)
  13. self.cmpl_variableDeclaration(node.varList)
  14. self.scope.frame.file = node.file
  15. return self.cmpl_evaluate_nodeStatementList(node.body)
  16. }
  17. func (self *_runtime) cmpl_call_nodeFunction(function *_object, stash *_fnStash, node *_nodeFunctionLiteral, this Value, argumentList []Value) Value {
  18. indexOfParameterName := make([]string, len(argumentList))
  19. // function(abc, def, ghi)
  20. // indexOfParameterName[0] = "abc"
  21. // indexOfParameterName[1] = "def"
  22. // indexOfParameterName[2] = "ghi"
  23. // ...
  24. argumentsFound := false
  25. for index, name := range node.parameterList {
  26. if name == "arguments" {
  27. argumentsFound = true
  28. }
  29. value := Value{}
  30. if index < len(argumentList) {
  31. value = argumentList[index]
  32. indexOfParameterName[index] = name
  33. }
  34. // strict = false
  35. self.scope.lexical.setValue(name, value, false)
  36. }
  37. if !argumentsFound {
  38. arguments := self.newArgumentsObject(indexOfParameterName, stash, len(argumentList))
  39. arguments.defineProperty("callee", toValue_object(function), 0101, false)
  40. stash.arguments = arguments
  41. // strict = false
  42. self.scope.lexical.setValue("arguments", toValue_object(arguments), false)
  43. for index, _ := range argumentList {
  44. if index < len(node.parameterList) {
  45. continue
  46. }
  47. indexAsString := strconv.FormatInt(int64(index), 10)
  48. arguments.defineProperty(indexAsString, argumentList[index], 0111, false)
  49. }
  50. }
  51. self.cmpl_functionDeclaration(node.functionList)
  52. self.cmpl_variableDeclaration(node.varList)
  53. result := self.cmpl_evaluate_nodeStatement(node.body)
  54. if result.kind == valueResult {
  55. return result
  56. }
  57. return Value{}
  58. }
  59. func (self *_runtime) cmpl_functionDeclaration(list []*_nodeFunctionLiteral) {
  60. executionContext := self.scope
  61. eval := executionContext.eval
  62. stash := executionContext.variable
  63. for _, function := range list {
  64. name := function.name
  65. value := self.cmpl_evaluate_nodeExpression(function)
  66. if !stash.hasBinding(name) {
  67. stash.createBinding(name, eval == true, value)
  68. } else {
  69. // TODO 10.5.5.e
  70. stash.setBinding(name, value, false) // TODO strict
  71. }
  72. }
  73. }
  74. func (self *_runtime) cmpl_variableDeclaration(list []string) {
  75. executionContext := self.scope
  76. eval := executionContext.eval
  77. stash := executionContext.variable
  78. for _, name := range list {
  79. if !stash.hasBinding(name) {
  80. stash.createBinding(name, eval == true, Value{}) // TODO strict?
  81. }
  82. }
  83. }