Skip to content

Commit

Permalink
Simplification & refactor of (parts of) the runtime
Browse files Browse the repository at this point in the history
* Proper lowercasing for internal stuff
* *Environment => *_stash
* ExecutionContext => _scope
* Simpler & shallower call/construct mechanics
* Remove unnecessary fields & methods
* Better scoping (no more stack): []*_scope => _scope.outer
* Some speed improvements

In preparation for robertkrimen#66
  • Loading branch information
robertkrimen committed May 28, 2014
1 parent b7dd9df commit 9cd045e
Show file tree
Hide file tree
Showing 38 changed files with 1,787 additions and 1,744 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
.PHONY: otto assets underscore

TESTS := \
_evalDirectIndirect \
~

TEST := -v --run
TEST := -v --run Test\($(subst $(eval) ,\|,$(TESTS))\)
TEST := -v
TEST := -v --run Test\($(subst $(eval) ,\|,$(TESTS))\)
TEST := .

test: parser inline.go
Expand Down
1 change: 0 additions & 1 deletion bug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ func Test_issue73(t *testing.T) {
func Test_7_3_1(t *testing.T) {
tt(t, func() {
test(`
eval("var test7_3_1\u2028abc = 66;");
[ abc, typeof test7_3_1 ];
`, "66,undefined")
Expand Down
47 changes: 4 additions & 43 deletions builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package otto

import (
"encoding/hex"
"fmt"
"math"
"net/url"
"regexp"
Expand All @@ -20,9 +19,10 @@ func builtinGlobal_eval(call FunctionCall) Value {
}
runtime := call.runtime
program := runtime.cmpl_parseOrThrow(toString(src))
if call.evalHint {
runtime.EnterEvalExecutionContext(call)
defer runtime.LeaveExecutionContext()
if !call.eval {
// Not a direct call to eval, so we enter the global ExecutionContext
runtime.enterGlobalScope()
defer runtime.leaveScope()
}
returnValue := runtime.cmpl_evaluate_nodeProgram(program)
if returnValue.isEmpty() {
Expand Down Expand Up @@ -352,42 +352,3 @@ func builtinGlobal_escape(call FunctionCall) Value {
func builtinGlobal_unescape(call FunctionCall) Value {
return toValue_string(builtin_unescape(toString(call.Argument(0))))
}

// Error

func builtinError(call FunctionCall) Value {
return toValue_object(call.runtime.newError("", call.Argument(0)))
}

func builtinNewError(self *_object, _ Value, argumentList []Value) Value {
return toValue_object(self.runtime.newError("", valueOfArrayIndex(argumentList, 0)))
}

func builtinError_toString(call FunctionCall) Value {
thisObject := call.thisObject()
if thisObject == nil {
panic(newTypeError())
}

name := "Error"
nameValue := thisObject.get("name")
if nameValue.IsDefined() {
name = toString(nameValue)
}

message := ""
messageValue := thisObject.get("message")
if messageValue.IsDefined() {
message = toString(messageValue)
}

if len(name) == 0 {
return toValue_string(message)
}

if len(message) == 0 {
return toValue_string(name)
}

return toValue_string(fmt.Sprintf("%s: %s", name, message))
}
6 changes: 3 additions & 3 deletions builtin_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func builtinArray(call FunctionCall) Value {
return toValue_object(builtinNewArrayNative(call.runtime, call.ArgumentList))
}

func builtinNewArray(self *_object, _ Value, argumentList []Value) Value {
func builtinNewArray(self *_object, argumentList []Value) Value {
return toValue_object(builtinNewArrayNative(self.runtime, argumentList))
}

Expand All @@ -30,7 +30,7 @@ func builtinArray_toString(call FunctionCall) Value {
join := thisObject.get("join")
if join.isCallable() {
join := join._object()
return join.Call(call.This, call.ArgumentList)
return join.call(call.This, call.ArgumentList, false)
}
return builtinObject_toString(call)
}
Expand Down Expand Up @@ -382,7 +382,7 @@ func sortCompare(thisObject *_object, index0, index1 uint, compare *_object) int
return 1
}

return int(toInt32(compare.Call(UndefinedValue(), []Value{x, y})))
return int(toInt32(compare.call(UndefinedValue(), []Value{x, y}, false)))
}

func arraySortSwap(thisObject *_object, index0, index1 uint) {
Expand Down
2 changes: 1 addition & 1 deletion builtin_boolean.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ func builtinBoolean(call FunctionCall) Value {
return toValue_bool(toBoolean(call.Argument(0)))
}

func builtinNewBoolean(self *_object, _ Value, argumentList []Value) Value {
func builtinNewBoolean(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newBoolean(valueOfArrayIndex(argumentList, 0)))
}

Expand Down
2 changes: 1 addition & 1 deletion builtin_date.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func builtinDate(call FunctionCall) Value {
return toValue_string(date.Time().Format(builtinDate_goDateTimeLayout))
}

func builtinNewDate(self *_object, _ Value, argumentList []Value) Value {
func builtinNewDate(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newDate(newDateTime(argumentList, Time.Local)))
}

Expand Down
65 changes: 53 additions & 12 deletions builtin_error.go
Original file line number Diff line number Diff line change
@@ -1,85 +1,126 @@
package otto

import (
"fmt"
)

func builtinError(call FunctionCall) Value {
return toValue_object(call.runtime.newError("", call.Argument(0)))
}

func builtinNewError(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newError("", valueOfArrayIndex(argumentList, 0)))
}

func builtinError_toString(call FunctionCall) Value {
thisObject := call.thisObject()
if thisObject == nil {
panic(newTypeError())
}

name := "Error"
nameValue := thisObject.get("name")
if nameValue.IsDefined() {
name = toString(nameValue)
}

message := ""
messageValue := thisObject.get("message")
if messageValue.IsDefined() {
message = toString(messageValue)
}

if len(name) == 0 {
return toValue_string(message)
}

if len(message) == 0 {
return toValue_string(name)
}

return toValue_string(fmt.Sprintf("%s: %s", name, message))
}

func (runtime *_runtime) newEvalError(message Value) *_object {
self := runtime.newErrorObject(message)
self.prototype = runtime.Global.EvalErrorPrototype
self.prototype = runtime.global.EvalErrorPrototype
return self
}

func builtinEvalError(call FunctionCall) Value {
return toValue_object(call.runtime.newEvalError(call.Argument(0)))
}

func builtinNewEvalError(self *_object, _ Value, argumentList []Value) Value {
func builtinNewEvalError(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newEvalError(valueOfArrayIndex(argumentList, 0)))
}

func (runtime *_runtime) newTypeError(message Value) *_object {
self := runtime.newErrorObject(message)
self.prototype = runtime.Global.TypeErrorPrototype
self.prototype = runtime.global.TypeErrorPrototype
return self
}

func builtinTypeError(call FunctionCall) Value {
return toValue_object(call.runtime.newTypeError(call.Argument(0)))
}

func builtinNewTypeError(self *_object, _ Value, argumentList []Value) Value {
func builtinNewTypeError(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newTypeError(valueOfArrayIndex(argumentList, 0)))
}

func (runtime *_runtime) newRangeError(message Value) *_object {
self := runtime.newErrorObject(message)
self.prototype = runtime.Global.RangeErrorPrototype
self.prototype = runtime.global.RangeErrorPrototype
return self
}

func builtinRangeError(call FunctionCall) Value {
return toValue_object(call.runtime.newRangeError(call.Argument(0)))
}

func builtinNewRangeError(self *_object, _ Value, argumentList []Value) Value {
func builtinNewRangeError(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newRangeError(valueOfArrayIndex(argumentList, 0)))
}

func (runtime *_runtime) newURIError(message Value) *_object {
self := runtime.newErrorObject(message)
self.prototype = runtime.Global.URIErrorPrototype
self.prototype = runtime.global.URIErrorPrototype
return self
}

func (runtime *_runtime) newReferenceError(message Value) *_object {
self := runtime.newErrorObject(message)
self.prototype = runtime.Global.ReferenceErrorPrototype
self.prototype = runtime.global.ReferenceErrorPrototype
return self
}

func builtinReferenceError(call FunctionCall) Value {
return toValue_object(call.runtime.newReferenceError(call.Argument(0)))
}

func builtinNewReferenceError(self *_object, _ Value, argumentList []Value) Value {
func builtinNewReferenceError(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newReferenceError(valueOfArrayIndex(argumentList, 0)))
}

func (runtime *_runtime) newSyntaxError(message Value) *_object {
self := runtime.newErrorObject(message)
self.prototype = runtime.Global.SyntaxErrorPrototype
self.prototype = runtime.global.SyntaxErrorPrototype
return self
}

func builtinSyntaxError(call FunctionCall) Value {
return toValue_object(call.runtime.newSyntaxError(call.Argument(0)))
}

func builtinNewSyntaxError(self *_object, _ Value, argumentList []Value) Value {
func builtinNewSyntaxError(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newSyntaxError(valueOfArrayIndex(argumentList, 0)))
}

func builtinURIError(call FunctionCall) Value {
return toValue_object(call.runtime.newURIError(call.Argument(0)))
}

func builtinNewURIError(self *_object, _ Value, argumentList []Value) Value {
func builtinNewURIError(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newURIError(valueOfArrayIndex(argumentList, 0)))
}
30 changes: 20 additions & 10 deletions builtin_function.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package otto

import (
"fmt"
"regexp"
"strings"
"unicode"
Expand All @@ -14,7 +15,7 @@ func builtinFunction(call FunctionCall) Value {
return toValue_object(builtinNewFunctionNative(call.runtime, call.ArgumentList))
}

func builtinNewFunction(self *_object, _ Value, argumentList []Value) Value {
func builtinNewFunction(self *_object, argumentList []Value) Value {
return toValue_object(builtinNewFunctionNative(self.runtime, argumentList))
}

Expand Down Expand Up @@ -47,12 +48,21 @@ func builtinNewFunctionNative(runtime *_runtime, argumentList []Value) *_object
runtime.parseThrow(err) // Will panic/throw appropriately
cmpl_function := parseExpression(function)

return runtime.newNodeFunction(cmpl_function.(*_nodeFunctionLiteral), runtime.GlobalEnvironment)
return runtime.newNodeFunction(cmpl_function.(*_nodeFunctionLiteral), runtime.globalStash)
}

func builtinFunction_toString(call FunctionCall) Value {
object := call.thisClassObject("Function") // Should throw a TypeError unless Function
return toValue_string(object.value.(_functionObject).source(object))
switch fn := object.value.(type) {
case _nativeFunctionObject:
return toValue_string(fmt.Sprintf("function %s() { [native code] }", fn.name))
case _nodeFunctionObject:
return toValue_string(fn.node.source)
case _bindFunctionObject:
return toValue_string("function () { [native code] }")
}

panic(newTypeError("Function.toString()"))
}

func builtinFunction_apply(call FunctionCall) Value {
Expand All @@ -62,12 +72,12 @@ func builtinFunction_apply(call FunctionCall) Value {
this := call.Argument(0)
if this.IsUndefined() {
// FIXME Not ECMA5
this = toValue_object(call.runtime.GlobalObject)
this = toValue_object(call.runtime.globalObject)
}
argumentList := call.Argument(1)
switch argumentList._valueType {
case valueUndefined, valueNull:
return call.thisObject().Call(this, []Value{})
return call.thisObject().call(this, nil, false)
case valueObject:
default:
panic(newTypeError())
Expand All @@ -80,7 +90,7 @@ func builtinFunction_apply(call FunctionCall) Value {
for index := int64(0); index < length; index++ {
valueArray[index] = arrayObject.get(arrayIndexToString(index))
}
return thisObject.Call(this, valueArray)
return thisObject.call(this, valueArray, false)
}

func builtinFunction_call(call FunctionCall) Value {
Expand All @@ -91,12 +101,12 @@ func builtinFunction_call(call FunctionCall) Value {
this := call.Argument(0)
if this.IsUndefined() {
// FIXME Not ECMA5
this = toValue_object(call.runtime.GlobalObject)
this = toValue_object(call.runtime.globalObject)
}
if len(call.ArgumentList) >= 1 {
return thisObject.Call(this, call.ArgumentList[1:])
return thisObject.call(this, call.ArgumentList[1:], false)
}
return thisObject.Call(this, []Value{})
return thisObject.call(this, nil, false)
}

func builtinFunction_bind(call FunctionCall) Value {
Expand All @@ -110,7 +120,7 @@ func builtinFunction_bind(call FunctionCall) Value {
argumentList := call.slice(1)
if this.IsUndefined() {
// FIXME Do this elsewhere?
this = toValue_object(call.runtime.GlobalObject)
this = toValue_object(call.runtime.globalObject)
}

return toValue_object(call.runtime.newBoundFunction(targetObject, this, argumentList))
Expand Down
2 changes: 1 addition & 1 deletion builtin_number.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func builtinNumber(call FunctionCall) Value {
return numberValueFromNumberArgumentList(call.ArgumentList)
}

func builtinNewNumber(self *_object, _ Value, argumentList []Value) Value {
func builtinNewNumber(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newNumber(numberValueFromNumberArgumentList(argumentList)))
}

Expand Down
2 changes: 1 addition & 1 deletion builtin_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func builtinObject(call FunctionCall) Value {
return toValue_object(call.runtime.toObject(value))
}

func builtinNewObject(self *_object, _ Value, argumentList []Value) Value {
func builtinNewObject(self *_object, argumentList []Value) Value {
value := valueOfArrayIndex(argumentList, 0)
switch value._valueType {
case valueNull, valueUndefined:
Expand Down
2 changes: 1 addition & 1 deletion builtin_regexp.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func builtinRegExp(call FunctionCall) Value {
return toValue_object(call.runtime.newRegExp(pattern, flags))
}

func builtinNewRegExp(self *_object, _ Value, argumentList []Value) Value {
func builtinNewRegExp(self *_object, argumentList []Value) Value {
return toValue_object(self.runtime.newRegExp(
valueOfArrayIndex(argumentList, 0),
valueOfArrayIndex(argumentList, 1),
Expand Down
Loading

0 comments on commit 9cd045e

Please sign in to comment.