Repository: robertkrimen/otto
Pull request #322 (2018-09-14 13:39:35)

replace single case type switches with if stmt
Found using https://go-critic.github.io/overview.html#singleCaseSwitch-ref


Patch:
diff --git a/.clog.toml b/.clog.toml
new file mode 100644
index 0000000..74e3702
--- /dev/null
+++ b/.clog.toml
@@ -0,0 +1,13 @@
+[clog]
+repository = "https://github.com/robertkrimen/otto"
+subtitle = "Release Notes"
+
+[sections]
+"Refactors" = ["refactor"]
+"Chores" = ["chore"]
+"Continuous Integration" = ["ci"]
+"Improvements" = ["imp", "improvement"]
+"Features" = ["feat", "feature"]
+"Legacy" = ["legacy"]
+"QA" = ["qa", "test", "tests"]
+"Documentation" = ["doc", "docs"]
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000..e9d7804
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,79 @@
+run:
+  concurrency: 4
+  deadline: 5m
+  skip-dirs:
+    - terst
+  skip-files:
+    - dbg/dbg.go
+
+linters-settings:
+  govet:
+    check-shadowing: false
+  gocyclo:
+    min-complexity: 20
+  maligned:
+    suggest-new: true
+  dupl:
+    threshold: 100
+  goconst:
+    min-len: 2
+    min-occurrences: 4
+  cyclop:
+    max-complexity: 15
+
+linters:
+  enable-all: true
+  disable:
+    - dupl
+    - gas
+    - errcheck
+    - gofmt
+    - gosimple
+    - interfacer
+    - megacheck
+    - maligned
+    - structcheck
+    - staticcheck
+    - unconvert
+    - unparam
+    - varcheck
+    - lll
+    - prealloc
+    - gochecknoglobals
+    - gochecknoinits
+    - scopelint
+    - funlen
+    - godox
+    - exhaustivestruct
+    - goerr113
+    - wsl
+    - nlreturn
+    - tagliatelle
+    - gomnd
+    - paralleltest
+    - wrapcheck
+    - testpackage
+    - golint
+    - gofumpt
+    - forbidigo
+    - gocognit
+    - gocritic
+    - godot
+    - nakedret
+    - nestif
+    - revive
+    - whitespace
+    - errorlint
+    - exhaustive
+    - forcetypeassert
+    - ifshort
+    - stylecheck
+    - gocyclo
+    - misspell
+    - cyclop
+
+issues:
+  exclude:
+    - .*Id.* should be .*ID.*
+  exclude-use-default: false
+  max-same-issues: 0
diff --git a/ast/comments.go b/ast/comments.go
index ef2cc3d..5c94855 100644
--- a/ast/comments.go
+++ b/ast/comments.go
@@ -2,6 +2,7 @@ package ast
 
 import (
 	"fmt"
+
 	"github.com/robertkrimen/otto/file"
 )
 
diff --git a/builtin.go b/builtin.go
index 256ee3c..4a899c8 100644
--- a/builtin.go
+++ b/builtin.go
@@ -41,22 +41,6 @@ func builtinGlobal_isFinite(call FunctionCall) Value {
 	return toValue_bool(!math.IsNaN(value) && !math.IsInf(value, 0))
 }
 
-// radix 3 => 2 (ASCII 50) +47
-// radix 11 => A/a (ASCII 65/97) +54/+86
-var parseInt_alphabetTable = func() []string {
-	table := []string{"", "", "01"}
-	for radix := 3; radix <= 36; radix += 1 {
-		alphabet := table[radix-1]
-		if radix <= 10 {
-			alphabet += string(radix + 47)
-		} else {
-			alphabet += string(radix+54) + string(radix+86)
-		}
-		table = append(table, alphabet)
-	}
-	return table
-}()
-
 func digitValue(chr rune) int {
 	switch {
 	case '0' <= chr && chr <= '9':
@@ -129,7 +113,7 @@ func builtinGlobal_parseInt(call FunctionCall) Value {
 			for _, chr := range input {
 				digit := float64(digitValue(chr))
 				if digit >= base {
-					goto error
+					return NaNValue()
 				}
 				value = value*base + digit
 			}
@@ -138,7 +122,6 @@ func builtinGlobal_parseInt(call FunctionCall) Value {
 			}
 			return toValue_float64(value)
 		}
-	error:
 		return NaNValue()
 	}
 	if negative {
diff --git a/builtin_array.go b/builtin_array.go
index 56dd95a..c31a070 100644
--- a/builtin_array.go
+++ b/builtin_array.go
@@ -38,7 +38,7 @@ func builtinArray_toString(call FunctionCall) Value {
 func builtinArray_toLocaleString(call FunctionCall) Value {
 	separator := ","
 	thisObject := call.thisObject()
-	length := int64(toUint32(thisObject.get("length")))
+	length := int64(toUint32(thisObject.get(propertyLength)))
 	if length == 0 {
 		return toValue_string("")
 	}
@@ -70,7 +70,7 @@ func builtinArray_concat(call FunctionCall) Value {
 		case valueObject:
 			object := item._object()
 			if isArray(object) {
-				length := object.get("length").number().int64
+				length := object.get(propertyLength).number().int64
 				for index := int64(0); index < length; index += 1 {
 					name := strconv.FormatInt(index, 10)
 					if object.hasProperty(name) {
@@ -91,9 +91,9 @@ func builtinArray_concat(call FunctionCall) Value {
 
 func builtinArray_shift(call FunctionCall) Value {
 	thisObject := call.thisObject()
-	length := int64(toUint32(thisObject.get("length")))
+	length := int64(toUint32(thisObject.get(propertyLength)))
 	if 0 == length {
-		thisObject.put("length", toValue_int64(0), true)
+		thisObject.put(propertyLength, toValue_int64(0), true)
 		return Value{}
 	}
 	first := thisObject.get("0")
@@ -107,34 +107,34 @@ func builtinArray_shift(call FunctionCall) Value {
 		}
 	}
 	thisObject.delete(arrayIndexToString(length-1), true)
-	thisObject.put("length", toValue_int64(length-1), true)
+	thisObject.put(propertyLength, toValue_int64(length-1), true)
 	return first
 }
 
 func builtinArray_push(call FunctionCall) Value {
 	thisObject := call.thisObject()
 	itemList := call.ArgumentList
-	index := int64(toUint32(thisObject.get("length")))
+	index := int64(toUint32(thisObject.get(propertyLength)))
 	for len(itemList) > 0 {
 		thisObject.put(arrayIndexToString(index), itemList[0], true)
 		itemList = itemList[1:]
 		index += 1
 	}
 	length := toValue_int64(index)
-	thisObject.put("length", length, true)
+	thisObject.put(propertyLength, length, true)
 	return length
 }
 
 func builtinArray_pop(call FunctionCall) Value {
 	thisObject := call.thisObject()
-	length := int64(toUint32(thisObject.get("length")))
+	length := int64(toUint32(thisObject.get(propertyLength)))
 	if 0 == length {
-		thisObject.put("length", toValue_uint32(0), true)
+		thisObject.put(propertyLength, toValue_uint32(0), true)
 		return Value{}
 	}
 	last := thisObject.get(arrayIndexToString(length - 1))
 	thisObject.delete(arrayIndexToString(length-1), true)
-	thisObject.put("length", toValue_int64(length-1), true)
+	thisObject.put(propertyLength, toValue_int64(length-1), true)
 	return last
 }
 
@@ -147,7 +147,7 @@ func builtinArray_join(call FunctionCall) Value {
 		}
 	}
 	thisObject := call.thisObject()
-	length := int64(toUint32(thisObject.get("length")))
+	length := int64(toUint32(thisObject.get(propertyLength)))
 	if length == 0 {
 		return toValue_string("")
 	}
@@ -167,7 +167,7 @@ func builtinArray_join(call FunctionCall) Value {
 
 func builtinArray_splice(call FunctionCall) Value {
 	thisObject := call.thisObject()
-	length := int64(toUint32(thisObject.get("length")))
+	length := int64(toUint32(thisObject.get(propertyLength)))
 
 	start := valueToRangeIndex(call.Argument(0), length, false)
 	deleteCount := length - start
@@ -240,7 +240,7 @@ func builtinArray_splice(call FunctionCall) Value {
 	for index := int64(0); index < itemCount; index++ {
 		thisObject.put(arrayIndexToString(index+start), itemList[index], true)
 	}
-	thisObject.put("length", toValue_int64(int64(length)+itemCount-deleteCount), true)
+	thisObject.put(propertyLength, toValue_int64(int64(length)+itemCount-deleteCount), true)
 
 	return toValue_object(call.runtime.newArrayOf(valueArray))
 }
@@ -248,7 +248,7 @@ func builtinArray_splice(call FunctionCall) Value {
 func builtinArray_slice(call FunctionCall) Value {
 	thisObject := call.thisObject()
 
-	length := int64(toUint32(thisObject.get("length")))
+	length := int64(toUint32(thisObject.get(propertyLength)))
 	start, end := rangeStartEnd(call.ArgumentList, length, false)
 
 	if start >= end {
@@ -270,7 +270,7 @@ func builtinArray_slice(call FunctionCall) Value {
 
 func builtinArray_unshift(call FunctionCall) Value {
 	thisObject := call.thisObject()
-	length := int64(toUint32(thisObject.get("length")))
+	length := int64(toUint32(thisObject.get(propertyLength)))
 	itemList := call.ArgumentList
 	itemCount := int64(len(itemList))
 
@@ -289,13 +289,13 @@ func builtinArray_unshift(call FunctionCall) Value {
 	}
 
 	newLength := toValue_int64(length + itemCount)
-	thisObject.put("length", newLength, true)
+	thisObject.put(propertyLength, newLength, true)
 	return newLength
 }
 
 func builtinArray_reverse(call FunctionCall) Value {
 	thisObject := call.thisObject()
-	length := int64(toUint32(thisObject.get("length")))
+	length := int64(toUint32(thisObject.get(propertyLength)))
 
 	lower := struct {
 		name   string
@@ -454,7 +454,7 @@ func arraySortQuickSort(thisObject *_object, left, right uint, compare *_object)
 
 func builtinArray_sort(call FunctionCall) Value {
 	thisObject := call.thisObject()
-	length := uint(toUint32(thisObject.get("length")))
+	length := uint(toUint32(thisObject.get(propertyLength)))
 	compareValue := call.Argument(0)
 	compare := compareValue._object()
 	if compareValue.IsUndefined() {
@@ -473,7 +473,7 @@ func builtinArray_isArray(call FunctionCall) Value {
 
 func builtinArray_indexOf(call FunctionCall) Value {
 	thisObject, matchValue := call.thisObject(), call.Argument(0)
-	if length := int64(toUint32(thisObject.get("length"))); length > 0 {
+	if length := int64(toUint32(thisObject.get(propertyLength))); length > 0 {
 		index := int64(0)
 		if len(call.ArgumentList) > 1 {
 			index = call.Argument(1).number().int64
@@ -501,7 +501,7 @@ func builtinArray_indexOf(call FunctionCall) Value {
 
 func builtinArray_lastIndexOf(call FunctionCall) Value {
 	thisObject, matchValue := call.thisObject(), call.Argument(0)
-	length := int64(toUint32(thisObject.get("length")))
+	length := int64(toUint32(thisObject.get(propertyLength)))
 	index := length - 1
 	if len(call.ArgumentList) > 1 {
 		index = call.Argument(1).number().int64
@@ -531,7 +531,7 @@ func builtinArray_every(call FunctionCall) Value {
 	thisObject := call.thisObject()
 	this := toValue_object(thisObject)
 	if iterator := call.Argument(0); iterator.isCallable() {
-		length := int64(toUint32(thisObject.get("length")))
+		length := int64(toUint32(thisObject.get(propertyLength)))
 		callThis := call.Argument(1)
 		for index := int64(0); index < length; index++ {
 			if key := arrayIndexToString(index); thisObject.hasProperty(key) {
@@ -550,7 +550,7 @@ func builtinArray_some(call FunctionCall) Value {
 	thisObject := call.thisObject()
 	this := toValue_object(thisObject)
 	if iterator := call.Argument(0); iterator.isCallable() {
-		length := int64(toUint32(thisObject.get("length")))
+		length := int64(toUint32(thisObject.get(propertyLength)))
 		callThis := call.Argument(1)
 		for index := int64(0); index < length; index++ {
 			if key := arrayIndexToString(index); thisObject.hasProperty(key) {
@@ -568,7 +568,7 @@ func builtinArray_forEach(call FunctionCall) Value {
 	thisObject := call.thisObject()
 	this := toValue_object(thisObject)
 	if iterator := call.Argument(0); iterator.isCallable() {
-		length := int64(toUint32(thisObject.get("length")))
+		length := int64(toUint32(thisObject.get(propertyLength)))
 		callThis := call.Argument(1)
 		for index := int64(0); index < length; index++ {
 			if key := arrayIndexToString(index); thisObject.hasProperty(key) {
@@ -584,7 +584,7 @@ func builtinArray_map(call FunctionCall) Value {
 	thisObject := call.thisObject()
 	this := toValue_object(thisObject)
 	if iterator := call.Argument(0); iterator.isCallable() {
-		length := int64(toUint32(thisObject.get("length")))
+		length := int64(toUint32(thisObject.get(propertyLength)))
 		callThis := call.Argument(1)
 		values := make([]Value, length)
 		for index := int64(0); index < length; index++ {
@@ -603,7 +603,7 @@ func builtinArray_filter(call FunctionCall) Value {
 	thisObject := call.thisObject()
 	this := toValue_object(thisObject)
 	if iterator := call.Argument(0); iterator.isCallable() {
-		length := int64(toUint32(thisObject.get("length")))
+		length := int64(toUint32(thisObject.get(propertyLength)))
 		callThis := call.Argument(1)
 		values := make([]Value, 0)
 		for index := int64(0); index < length; index++ {
@@ -625,7 +625,7 @@ func builtinArray_reduce(call FunctionCall) Value {
 	if iterator := call.Argument(0); iterator.isCallable() {
 		initial := len(call.ArgumentList) > 1
 		start := call.Argument(1)
-		length := int64(toUint32(thisObject.get("length")))
+		length := int64(toUint32(thisObject.get(propertyLength)))
 		index := int64(0)
 		if length > 0 || initial {
 			var accumulator Value
@@ -657,7 +657,7 @@ func builtinArray_reduceRight(call FunctionCall) Value {
 	if iterator := call.Argument(0); iterator.isCallable() {
 		initial := len(call.ArgumentList) > 1
 		start := call.Argument(1)
-		length := int64(toUint32(thisObject.get("length")))
+		length := int64(toUint32(thisObject.get(propertyLength)))
 		if length > 0 || initial {
 			index := length - 1
 			var accumulator Value
diff --git a/builtin_boolean.go b/builtin_boolean.go
index 59b8e78..25a596e 100644
--- a/builtin_boolean.go
+++ b/builtin_boolean.go
@@ -14,7 +14,7 @@ func builtinBoolean_toString(call FunctionCall) Value {
 	value := call.This
 	if !value.IsBoolean() {
 		// Will throw a TypeError if ThisObject is not a Boolean
-		value = call.thisClassObject("Boolean").primitiveValue()
+		value = call.thisClassObject(classBoolean).primitiveValue()
 	}
 	return toValue_string(value.string())
 }
@@ -22,7 +22,7 @@ func builtinBoolean_toString(call FunctionCall) Value {
 func builtinBoolean_valueOf(call FunctionCall) Value {
 	value := call.This
 	if !value.IsBoolean() {
-		value = call.thisClassObject("Boolean").primitiveValue()
+		value = call.thisClassObject(classBoolean).primitiveValue()
 	}
 	return value
 }
diff --git a/builtin_error.go b/builtin_error.go
index 41da84e..95f9cd9 100644
--- a/builtin_error.go
+++ b/builtin_error.go
@@ -5,11 +5,11 @@ import (
 )
 
 func builtinError(call FunctionCall) Value {
-	return toValue_object(call.runtime.newError("Error", call.Argument(0), 1))
+	return toValue_object(call.runtime.newError(classError, call.Argument(0), 1))
 }
 
 func builtinNewError(self *_object, argumentList []Value) Value {
-	return toValue_object(self.runtime.newError("Error", valueOfArrayIndex(argumentList, 0), 0))
+	return toValue_object(self.runtime.newError(classError, valueOfArrayIndex(argumentList, 0), 0))
 }
 
 func builtinError_toString(call FunctionCall) Value {
@@ -18,7 +18,7 @@ func builtinError_toString(call FunctionCall) Value {
 		panic(call.runtime.panicTypeError())
 	}
 
-	name := "Error"
+	name := classError
 	nameValue := thisObject.get("name")
 	if nameValue.IsDefined() {
 		name = nameValue.string()
diff --git a/builtin_function.go b/builtin_function.go
index 3d07566..f988c83 100644
--- a/builtin_function.go
+++ b/builtin_function.go
@@ -2,7 +2,6 @@ package otto
 
 import (
 	"fmt"
-	"regexp"
 	"strings"
 	"unicode"
 
@@ -30,8 +29,6 @@ func argumentList2parameterList(argumentList []Value) []string {
 	return parameterList
 }
 
-var matchIdentifier = regexp.MustCompile(`^[$_\p{L}][$_\p{L}\d}]*$`)
-
 func builtinNewFunctionNative(runtime *_runtime, argumentList []Value) *_object {
 	var parameterList, body string
 	count := len(argumentList)
@@ -54,7 +51,7 @@ func builtinNewFunctionNative(runtime *_runtime, argumentList []Value) *_object
 }
 
 func builtinFunction_toString(call FunctionCall) Value {
-	object := call.thisClassObject("Function") // Should throw a TypeError unless Function
+	object := call.thisClassObject(classFunction) // Should throw a TypeError unless Function
 	switch fn := object.value.(type) {
 	case _nativeFunctionObject:
 		return toValue_string(fmt.Sprintf("function %s() { [native code] }", fn.name))
@@ -87,7 +84,7 @@ func builtinFunction_apply(call FunctionCall) Value {
 
 	arrayObject := argumentList._object()
 	thisObject := call.thisObject()
-	length := int64(toUint32(arrayObject.get("length")))
+	length := int64(toUint32(arrayObject.get(propertyLength)))
 	valueArray := make([]Value, length)
 	for index := int64(0); index < length; index++ {
 		valueArray[index] = arrayObject.get(arrayIndexToString(index))
diff --git a/builtin_json.go b/builtin_json.go
index aed54bf..adfc76f 100644
--- a/builtin_json.go
+++ b/builtin_json.go
@@ -123,8 +123,8 @@ func builtinJSON_stringify(call FunctionCall) Value {
 				switch value.kind {
 				case valueObject:
 					switch value.value.(*_object).class {
-					case "String":
-					case "Number":
+					case classString:
+					case classNumber:
 					default:
 						continue
 					}
@@ -142,7 +142,7 @@ func builtinJSON_stringify(call FunctionCall) Value {
 				propertyList[index] = name
 			}
 			ctx.propertyList = propertyList[0:length]
-		} else if replacer.class == "Function" {
+		} else if replacer.class == classFunction {
 			value := toValue_object(replacer)
 			ctx.replacerFunction = &value
 		}
@@ -150,9 +150,9 @@ func builtinJSON_stringify(call FunctionCall) Value {
 	if spaceValue, exists := call.getArgument(2); exists {
 		if spaceValue.kind == valueObject {
 			switch spaceValue.value.(*_object).class {
-			case "String":
+			case classString:
 				spaceValue = toValue_string(spaceValue.string())
-			case "Number":
+			case classNumber:
 				spaceValue = spaceValue.numberValue()
 			}
 		}
@@ -211,16 +211,16 @@ func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, ho
 	}
 
 	if ctx.replacerFunction != nil {
-		value = (*ctx.replacerFunction).call(ctx.call.runtime, toValue_object(holder), key, value)
+		value = ctx.replacerFunction.call(ctx.call.runtime, toValue_object(holder), key, value)
 	}
 
 	if value.kind == valueObject {
 		switch value.value.(*_object).class {
-		case "Boolean":
+		case classBoolean:
 			value = value._object().value.(Value)
-		case "String":
+		case classString:
 			value = toValue_string(value.string())
-		case "Number":
+		case classNumber:
 			value = value.numberValue()
 		}
 	}
@@ -255,7 +255,7 @@ func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, ho
 		}
 		if isArray(holder) {
 			var length uint32
-			switch value := holder.get("length").value.(type) {
+			switch value := holder.get(propertyLength).value.(type) {
 			case uint32:
 				length = value
 			case int:
@@ -272,7 +272,7 @@ func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, ho
 				array[index] = value
 			}
 			return array, true
-		} else if holder.class != "Function" {
+		} else if holder.class != classFunction {
 			object := map[string]interface{}{}
 			if ctx.propertyList != nil {
 				for _, name := range ctx.propertyList {
diff --git a/builtin_number.go b/builtin_number.go
index f99a42a..6996a8e 100644
--- a/builtin_number.go
+++ b/builtin_number.go
@@ -24,7 +24,7 @@ func builtinNewNumber(self *_object, argumentList []Value) Value {
 
 func builtinNumber_toString(call FunctionCall) Value {
 	// Will throw a TypeError if ThisObject is not a Number
-	value := call.thisClassObject("Number").primitiveValue()
+	value := call.thisClassObject(classNumber).primitiveValue()
 	radix := 10
 	radixArgument := call.Argument(0)
 	if radixArgument.IsDefined() {
@@ -41,7 +41,7 @@ func builtinNumber_toString(call FunctionCall) Value {
 }
 
 func builtinNumber_valueOf(call FunctionCall) Value {
-	return call.thisClassObject("Number").primitiveValue()
+	return call.thisClassObject(classNumber).primitiveValue()
 }
 
 func builtinNumber_toFixed(call FunctionCall) Value {
@@ -88,6 +88,13 @@ func builtinNumber_toPrecision(call FunctionCall) Value {
 	return toValue_string(strconv.FormatFloat(call.This.float64(), 'g', int(precision), 64))
 }
 
+func builtinNumber_isNaN(call FunctionCall) Value {
+	if len(call.ArgumentList) < 1 {
+		return toValue_bool(false)
+	}
+	return toValue_bool(call.Argument(0).IsNaN())
+}
+
 func builtinNumber_toLocaleString(call FunctionCall) Value {
 	return builtinNumber_toString(call)
 }
diff --git a/builtin_object.go b/builtin_object.go
index c2433f7..f9a39d3 100644
--- a/builtin_object.go
+++ b/builtin_object.go
@@ -66,7 +66,7 @@ func builtinObject_propertyIsEnumerable(call FunctionCall) Value {
 }
 
 func builtinObject_toString(call FunctionCall) Value {
-	result := ""
+	var result string
 	if call.This.IsUndefined() {
 		result = "[object Undefined]"
 	} else if call.This.IsNull() {
diff --git a/builtin_regexp.go b/builtin_regexp.go
index 9942251..dfa84e3 100644
--- a/builtin_regexp.go
+++ b/builtin_regexp.go
@@ -10,7 +10,7 @@ func builtinRegExp(call FunctionCall) Value {
 	pattern := call.Argument(0)
 	flags := call.Argument(1)
 	if object := pattern._object(); object != nil {
-		if object.class == "RegExp" && flags.IsUndefined() {
+		if object.class == classRegExp && flags.IsUndefined() {
 			return pattern
 		}
 	}
diff --git a/builtin_string.go b/builtin_string.go
index 6a17184..0c21d83 100644
--- a/builtin_string.go
+++ b/builtin_string.go
@@ -26,10 +26,10 @@ func builtinNewString(self *_object, argumentList []Value) Value {
 }
 
 func builtinString_toString(call FunctionCall) Value {
-	return call.thisClassObject("String").primitiveValue()
+	return call.thisClassObject(classString).primitiveValue()
 }
 func builtinString_valueOf(call FunctionCall) Value {
-	return call.thisClassObject("String").primitiveValue()
+	return call.thisClassObject(classString).primitiveValue()
 }
 
 func builtinString_fromCharCode(call FunctionCall) Value {
@@ -124,7 +124,7 @@ func builtinString_match(call FunctionCall) Value {
 	target := call.This.string()
 	matcherValue := call.Argument(0)
 	matcher := matcherValue._object()
-	if !matcherValue.IsObject() || matcher.class != "RegExp" {
+	if !matcherValue.IsObject() || matcher.class != classRegExp {
 		matcher = call.runtime.newRegExp(matcherValue, Value{})
 	}
 	global := matcher.get("global").bool()
@@ -138,12 +138,11 @@ func builtinString_match(call FunctionCall) Value {
 
 	{
 		result := matcher.regExpValue().regularExpression.FindAllStringIndex(target, -1)
-		matchCount := len(result)
 		if result == nil {
 			matcher.put("lastIndex", toValue_int(0), true)
 			return Value{} // !match
 		}
-		matchCount = len(result)
+		matchCount := len(result)
 		valueArray := make([]Value, matchCount)
 		for index := 0; index < matchCount; index++ {
 			valueArray[index] = toValue_string(target[result[index][0]:result[index][1]])
@@ -173,9 +172,12 @@ func builtinString_findAndReplaceString(input []byte, lastIndex int, match []int
 		case '\'':
 			return target[match[1]:len(target)]
 		}
-		matchNumberParse, error := strconv.ParseInt(string(part[1:]), 10, 64)
+		matchNumberParse, err := strconv.ParseInt(string(part[1:]), 10, 64)
+		if err != nil {
+			return []byte{}
+		}
 		matchNumber := int(matchNumberParse)
-		if error != nil || matchNumber >= matchCount {
+		if matchNumber >= matchCount {
 			return []byte{}
 		}
 		offset := 2 * matchNumber
@@ -198,7 +200,7 @@ func builtinString_replace(call FunctionCall) Value {
 	var search *regexp.Regexp
 	global := false
 	find := 1
-	if searchValue.IsObject() && searchObject.class == "RegExp" {
+	if searchValue.IsObject() && searchObject.class == classRegExp {
 		regExp := searchObject.regExpValue()
 		search = regExp.regularExpression
 		if regExp.global {
@@ -267,7 +269,7 @@ func builtinString_search(call FunctionCall) Value {
 	target := call.This.string()
 	searchValue := call.Argument(0)
 	search := searchValue._object()
-	if !searchValue.IsObject() || search.class != "RegExp" {
+	if !searchValue.IsObject() || search.class != classRegExp {
 		search = call.runtime.newRegExp(searchValue, Value{})
 	}
 	result := search.regExpValue().regularExpression.FindStringIndex(target)
@@ -277,17 +279,6 @@ func builtinString_search(call FunctionCall) Value {
 	return toValue_int(result[0])
 }
 
-func stringSplitMatch(target string, targetLength int64, index uint, search string, searchLength int64) (bool, uint) {
-	if int64(index)+searchLength > searchLength {
-		return false, 0
-	}
-	found := strings.Index(target[index:], search)
-	if 0 > found {
-		return false, 0
-	}
-	return true, uint(found)
-}
-
 func builtinString_split(call FunctionCall) Value {
 	checkObjectCoercible(call.runtime, call.This)
 	target := call.This.string()
diff --git a/cmpl.go b/cmpl.go
index c191b45..0153159 100644
--- a/cmpl.go
+++ b/cmpl.go
@@ -5,12 +5,6 @@ import (
 	"github.com/robertkrimen/otto/file"
 )
 
-type _file struct {
-	name string
-	src  string
-	base int // This will always be 1 or greater
-}
-
 type _compiler struct {
 	file    *file.File
 	program *ast.Program
diff --git a/consts.go b/consts.go
new file mode 100644
index 0000000..ac8dc44
--- /dev/null
+++ b/consts.go
@@ -0,0 +1,18 @@
+package otto
+
+const (
+	// Common classes.
+	classString   = "String"
+	classGoArray  = "GoArray"
+	classNumber   = "Number"
+	classDate     = "Date"
+	classArray    = "Array"
+	classFunction = "Function"
+	classObject   = "Object"
+	classRegExp   = "RegExp"
+	classBoolean  = "Boolean"
+	classError    = "Error"
+
+	// Common properties.
+	propertyLength = "length"
+)
diff --git a/evaluate.go b/evaluate.go
index 093054c..28fb2e6 100644
--- a/evaluate.go
+++ b/evaluate.go
@@ -140,23 +140,6 @@ func (self *_runtime) calculateBinaryExpression(operator token.Token, left Value
 	panic(hereBeDragons(operator))
 }
 
-func valueKindDispatchKey(left _valueKind, right _valueKind) int {
-	return (int(left) << 2) + int(right)
-}
-
-var equalDispatch map[int](func(Value, Value) bool) = makeEqualDispatch()
-
-func makeEqualDispatch() map[int](func(Value, Value) bool) {
-	key := valueKindDispatchKey
-	return map[int](func(Value, Value) bool){
-
-		key(valueNumber, valueObject): func(x Value, y Value) bool { return x.float64() == y.float64() },
-		key(valueString, valueObject): func(x Value, y Value) bool { return x.float64() == y.float64() },
-		key(valueObject, valueNumber): func(x Value, y Value) bool { return x.float64() == y.float64() },
-		key(valueObject, valueString): func(x Value, y Value) bool { return x.float64() == y.float64() },
-	}
-}
-
 type _lessThanResult int
 
 const (
@@ -166,10 +149,7 @@ const (
 )
 
 func calculateLessThan(left Value, right Value, leftFirst bool) _lessThanResult {
-
-	x := Value{}
-	y := x
-
+	var x, y Value
 	if leftFirst {
 		x = toNumberPrimitive(left)
 		y = toNumberPrimitive(right)
@@ -178,7 +158,7 @@ func calculateLessThan(left Value, right Value, leftFirst bool) _lessThanResult
 		x = toNumberPrimitive(left)
 	}
 
-	result := false
+	var result bool
 	if x.kind != valueString || y.kind != valueString {
 		x, y := x.float64(), y.float64()
 		if math.IsNaN(x) || math.IsNaN(y) {
diff --git a/global.go b/global.go
index eb2a2a0..c0f5580 100644
--- a/global.go
+++ b/global.go
@@ -90,7 +90,7 @@ func (self *_object) hasPrimitive() bool {
 }
 
 func (runtime *_runtime) newObject() *_object {
-	self := runtime.newClassObject("Object")
+	self := runtime.newClassObject(classObject)
 	self.prototype = runtime.global.ObjectPrototype
 	return self
 }
@@ -134,7 +134,7 @@ func (runtime *_runtime) newRegExp(patternValue Value, flagsValue Value) *_objec
 
 	pattern := ""
 	flags := ""
-	if object := patternValue._object(); object != nil && object.class == "RegExp" {
+	if object := patternValue._object(); object != nil && object.class == classRegExp {
 		if flagsValue.IsDefined() {
 			panic(runtime.panicTypeError("Cannot supply flags when constructing one RegExp from another"))
 		}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..e4689b8
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,10 @@
+module github.com/robertkrimen/otto
+
+go 1.14
+
+require (
+	github.com/chzyer/logex v1.1.10 // indirect
+	github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect
+	gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375
+	gopkg.in/sourcemap.v1 v1.0.5
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..aa2319a
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,8 @@
+github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375 h1:hPki/oSSWOLiI9Gc9jyIoj33O3j29fUc9PlLha2yDj0=
+gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ=
+gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
+gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
diff --git a/inline.go b/inline.go
index 6e5df83..d599b17 100644
--- a/inline.go
+++ b/inline.go
@@ -8,7 +8,7 @@ func _newContext(runtime *_runtime) {
 	{
 		runtime.global.ObjectPrototype = &_object{
 			runtime:     runtime,
-			class:       "Object",
+			class:       classObject,
 			objectClass: _classObject,
 			prototype:   nil,
 			extensible:  true,
@@ -18,7 +18,7 @@ func _newContext(runtime *_runtime) {
 	{
 		runtime.global.FunctionPrototype = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.ObjectPrototype,
 			extensible:  true,
@@ -28,12 +28,12 @@ func _newContext(runtime *_runtime) {
 	{
 		valueOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -42,7 +42,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "valueOf",
@@ -51,12 +51,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -65,7 +65,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toString",
@@ -74,12 +74,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toLocaleString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -88,7 +88,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toLocaleString",
@@ -97,12 +97,12 @@ func _newContext(runtime *_runtime) {
 		}
 		hasOwnProperty_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -111,7 +111,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "hasOwnProperty",
@@ -120,12 +120,12 @@ func _newContext(runtime *_runtime) {
 		}
 		isPrototypeOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -134,7 +134,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "isPrototypeOf",
@@ -143,12 +143,12 @@ func _newContext(runtime *_runtime) {
 		}
 		propertyIsEnumerable_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -157,7 +157,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "propertyIsEnumerable",
@@ -225,12 +225,12 @@ func _newContext(runtime *_runtime) {
 	{
 		toString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -239,7 +239,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toString",
@@ -248,12 +248,12 @@ func _newContext(runtime *_runtime) {
 		}
 		apply_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -262,7 +262,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "apply",
@@ -271,12 +271,12 @@ func _newContext(runtime *_runtime) {
 		}
 		call_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -285,7 +285,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "call",
@@ -294,12 +294,12 @@ func _newContext(runtime *_runtime) {
 		}
 		bind_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -308,7 +308,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "bind",
@@ -348,7 +348,7 @@ func _newContext(runtime *_runtime) {
 				mode:  0101,
 				value: Value{},
 			},
-			"length": _property{
+			propertyLength: _property{
 				mode: 0,
 				value: Value{
 					kind:  valueNumber,
@@ -362,18 +362,18 @@ func _newContext(runtime *_runtime) {
 			"call",
 			"bind",
 			"constructor",
-			"length",
+			propertyLength,
 		}
 	}
 	{
 		getPrototypeOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -382,7 +382,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getPrototypeOf",
@@ -391,12 +391,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getOwnPropertyDescriptor_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -405,7 +405,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getOwnPropertyDescriptor",
@@ -414,12 +414,12 @@ func _newContext(runtime *_runtime) {
 		}
 		defineProperty_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -428,7 +428,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "defineProperty",
@@ -437,12 +437,12 @@ func _newContext(runtime *_runtime) {
 		}
 		defineProperties_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -451,7 +451,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "defineProperties",
@@ -460,12 +460,12 @@ func _newContext(runtime *_runtime) {
 		}
 		create_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -474,7 +474,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "create",
@@ -483,12 +483,12 @@ func _newContext(runtime *_runtime) {
 		}
 		isExtensible_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -497,7 +497,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "isExtensible",
@@ -506,12 +506,12 @@ func _newContext(runtime *_runtime) {
 		}
 		preventExtensions_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -520,7 +520,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "preventExtensions",
@@ -529,12 +529,12 @@ func _newContext(runtime *_runtime) {
 		}
 		isSealed_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -543,7 +543,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "isSealed",
@@ -552,12 +552,12 @@ func _newContext(runtime *_runtime) {
 		}
 		seal_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -566,7 +566,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "seal",
@@ -575,12 +575,12 @@ func _newContext(runtime *_runtime) {
 		}
 		isFrozen_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -589,7 +589,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "isFrozen",
@@ -598,12 +598,12 @@ func _newContext(runtime *_runtime) {
 		}
 		freeze_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -612,7 +612,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "freeze",
@@ -621,12 +621,12 @@ func _newContext(runtime *_runtime) {
 		}
 		keys_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -635,7 +635,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "keys",
@@ -644,12 +644,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getOwnPropertyNames_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -658,7 +658,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getOwnPropertyNames",
@@ -667,17 +667,17 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.Object = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			value: _nativeFunctionObject{
-				name:      "Object",
+				name:      classObject,
 				call:      builtinObject,
 				construct: builtinNewObject,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -784,7 +784,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 				"getPrototypeOf",
 				"getOwnPropertyDescriptor",
@@ -813,17 +813,17 @@ func _newContext(runtime *_runtime) {
 	{
 		Function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			value: _nativeFunctionObject{
-				name:      "Function",
+				name:      classFunction,
 				call:      builtinFunction,
 				construct: builtinNewFunction,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -839,7 +839,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 			},
 		}
@@ -856,12 +856,12 @@ func _newContext(runtime *_runtime) {
 	{
 		toString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -870,7 +870,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toString",
@@ -879,12 +879,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toLocaleString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -893,7 +893,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toLocaleString",
@@ -902,12 +902,12 @@ func _newContext(runtime *_runtime) {
 		}
 		concat_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -916,7 +916,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "concat",
@@ -925,12 +925,12 @@ func _newContext(runtime *_runtime) {
 		}
 		join_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -939,7 +939,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "join",
@@ -948,12 +948,12 @@ func _newContext(runtime *_runtime) {
 		}
 		splice_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -962,7 +962,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "splice",
@@ -971,12 +971,12 @@ func _newContext(runtime *_runtime) {
 		}
 		shift_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -985,7 +985,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "shift",
@@ -994,12 +994,12 @@ func _newContext(runtime *_runtime) {
 		}
 		pop_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1008,7 +1008,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "pop",
@@ -1017,12 +1017,12 @@ func _newContext(runtime *_runtime) {
 		}
 		push_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1031,7 +1031,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "push",
@@ -1040,12 +1040,12 @@ func _newContext(runtime *_runtime) {
 		}
 		slice_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1054,7 +1054,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "slice",
@@ -1063,12 +1063,12 @@ func _newContext(runtime *_runtime) {
 		}
 		unshift_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1077,7 +1077,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "unshift",
@@ -1086,12 +1086,12 @@ func _newContext(runtime *_runtime) {
 		}
 		reverse_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1100,7 +1100,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "reverse",
@@ -1109,12 +1109,12 @@ func _newContext(runtime *_runtime) {
 		}
 		sort_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1123,7 +1123,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "sort",
@@ -1132,12 +1132,12 @@ func _newContext(runtime *_runtime) {
 		}
 		indexOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1146,7 +1146,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "indexOf",
@@ -1155,12 +1155,12 @@ func _newContext(runtime *_runtime) {
 		}
 		lastIndexOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1169,7 +1169,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "lastIndexOf",
@@ -1178,12 +1178,12 @@ func _newContext(runtime *_runtime) {
 		}
 		every_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1192,7 +1192,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "every",
@@ -1201,12 +1201,12 @@ func _newContext(runtime *_runtime) {
 		}
 		some_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1215,7 +1215,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "some",
@@ -1224,12 +1224,12 @@ func _newContext(runtime *_runtime) {
 		}
 		forEach_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1238,7 +1238,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "forEach",
@@ -1247,12 +1247,12 @@ func _newContext(runtime *_runtime) {
 		}
 		map_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1261,7 +1261,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "map",
@@ -1270,12 +1270,12 @@ func _newContext(runtime *_runtime) {
 		}
 		filter_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1284,7 +1284,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "filter",
@@ -1293,12 +1293,12 @@ func _newContext(runtime *_runtime) {
 		}
 		reduce_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1307,7 +1307,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "reduce",
@@ -1316,12 +1316,12 @@ func _newContext(runtime *_runtime) {
 		}
 		reduceRight_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1330,7 +1330,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "reduceRight",
@@ -1339,12 +1339,12 @@ func _newContext(runtime *_runtime) {
 		}
 		isArray_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1353,7 +1353,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "isArray",
@@ -1362,13 +1362,13 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.ArrayPrototype = &_object{
 			runtime:     runtime,
-			class:       "Array",
+			class:       classArray,
 			objectClass: _classArray,
 			prototype:   runtime.global.ObjectPrototype,
 			extensible:  true,
 			value:       nil,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0100,
 					value: Value{
 						kind:  valueNumber,
@@ -1524,7 +1524,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"toString",
 				"toLocaleString",
 				"concat",
@@ -1550,17 +1550,17 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.Array = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			value: _nativeFunctionObject{
-				name:      "Array",
+				name:      classArray,
 				call:      builtinArray,
 				construct: builtinNewArray,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1583,7 +1583,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 				"isArray",
 			},
@@ -1600,12 +1600,12 @@ func _newContext(runtime *_runtime) {
 	{
 		toString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1614,7 +1614,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toString",
@@ -1623,12 +1623,12 @@ func _newContext(runtime *_runtime) {
 		}
 		valueOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1637,7 +1637,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "valueOf",
@@ -1646,12 +1646,12 @@ func _newContext(runtime *_runtime) {
 		}
 		charAt_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1660,7 +1660,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "charAt",
@@ -1669,12 +1669,12 @@ func _newContext(runtime *_runtime) {
 		}
 		charCodeAt_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1683,7 +1683,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "charCodeAt",
@@ -1692,12 +1692,12 @@ func _newContext(runtime *_runtime) {
 		}
 		concat_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1706,7 +1706,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "concat",
@@ -1715,12 +1715,12 @@ func _newContext(runtime *_runtime) {
 		}
 		indexOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1729,7 +1729,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "indexOf",
@@ -1738,12 +1738,12 @@ func _newContext(runtime *_runtime) {
 		}
 		lastIndexOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1752,7 +1752,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "lastIndexOf",
@@ -1761,12 +1761,12 @@ func _newContext(runtime *_runtime) {
 		}
 		match_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1775,7 +1775,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "match",
@@ -1784,12 +1784,12 @@ func _newContext(runtime *_runtime) {
 		}
 		replace_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1798,7 +1798,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "replace",
@@ -1807,12 +1807,12 @@ func _newContext(runtime *_runtime) {
 		}
 		search_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1821,7 +1821,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "search",
@@ -1830,12 +1830,12 @@ func _newContext(runtime *_runtime) {
 		}
 		split_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1844,7 +1844,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "split",
@@ -1853,12 +1853,12 @@ func _newContext(runtime *_runtime) {
 		}
 		slice_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1867,7 +1867,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "slice",
@@ -1876,12 +1876,12 @@ func _newContext(runtime *_runtime) {
 		}
 		substring_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1890,7 +1890,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "substring",
@@ -1899,12 +1899,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toLowerCase_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1913,7 +1913,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toLowerCase",
@@ -1922,12 +1922,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toUpperCase_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1936,7 +1936,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toUpperCase",
@@ -1945,12 +1945,12 @@ func _newContext(runtime *_runtime) {
 		}
 		substr_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1959,7 +1959,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "substr",
@@ -1968,12 +1968,12 @@ func _newContext(runtime *_runtime) {
 		}
 		trim_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -1982,7 +1982,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "trim",
@@ -1991,12 +1991,12 @@ func _newContext(runtime *_runtime) {
 		}
 		trimLeft_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2005,7 +2005,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "trimLeft",
@@ -2014,12 +2014,12 @@ func _newContext(runtime *_runtime) {
 		}
 		trimRight_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2028,7 +2028,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "trimRight",
@@ -2037,12 +2037,12 @@ func _newContext(runtime *_runtime) {
 		}
 		localeCompare_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2051,7 +2051,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "localeCompare",
@@ -2060,12 +2060,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toLocaleLowerCase_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2074,7 +2074,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toLocaleLowerCase",
@@ -2083,12 +2083,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toLocaleUpperCase_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2097,7 +2097,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toLocaleUpperCase",
@@ -2106,12 +2106,12 @@ func _newContext(runtime *_runtime) {
 		}
 		fromCharCode_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2120,7 +2120,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "fromCharCode",
@@ -2129,13 +2129,13 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.StringPrototype = &_object{
 			runtime:     runtime,
-			class:       "String",
+			class:       classString,
 			objectClass: _classString,
 			prototype:   runtime.global.ObjectPrototype,
 			extensible:  true,
 			value:       prototypeValueString,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2298,7 +2298,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"toString",
 				"valueOf",
 				"charAt",
@@ -2325,17 +2325,17 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.String = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			value: _nativeFunctionObject{
-				name:      "String",
+				name:      classString,
 				call:      builtinString,
 				construct: builtinNewString,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2358,7 +2358,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 				"fromCharCode",
 			},
@@ -2375,12 +2375,12 @@ func _newContext(runtime *_runtime) {
 	{
 		toString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2389,7 +2389,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toString",
@@ -2398,12 +2398,12 @@ func _newContext(runtime *_runtime) {
 		}
 		valueOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2412,7 +2412,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "valueOf",
@@ -2421,7 +2421,7 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.BooleanPrototype = &_object{
 			runtime:     runtime,
-			class:       "Boolean",
+			class:       classBoolean,
 			objectClass: _classObject,
 			prototype:   runtime.global.ObjectPrototype,
 			extensible:  true,
@@ -2449,17 +2449,17 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.Boolean = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			value: _nativeFunctionObject{
-				name:      "Boolean",
+				name:      classBoolean,
 				call:      builtinBoolean,
 				construct: builtinNewBoolean,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2475,7 +2475,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 			},
 		}
@@ -2491,12 +2491,12 @@ func _newContext(runtime *_runtime) {
 	{
 		toString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2505,7 +2505,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toString",
@@ -2514,12 +2514,12 @@ func _newContext(runtime *_runtime) {
 		}
 		valueOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2528,7 +2528,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "valueOf",
@@ -2537,12 +2537,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toFixed_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2551,7 +2551,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toFixed",
@@ -2560,12 +2560,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toExponential_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2574,7 +2574,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toExponential",
@@ -2583,12 +2583,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toPrecision_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2597,7 +2597,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toPrecision",
@@ -2606,12 +2606,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toLocaleString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2620,16 +2620,39 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toLocaleString",
 				call: builtinNumber_toLocaleString,
 			},
 		}
+		isNaN_function := &_object{
+			runtime:     runtime,
+			class:       classFunction,
+			objectClass: _classObject,
+			prototype:   runtime.global.FunctionPrototype,
+			extensible:  true,
+			property: map[string]_property{
+				propertyLength: _property{
+					mode: 0,
+					value: Value{
+						kind:  valueNumber,
+						value: 1,
+					},
+				},
+			},
+			propertyOrder: []string{
+				propertyLength,
+			},
+			value: _nativeFunctionObject{
+				name: "isNaN",
+				call: builtinNumber_isNaN,
+			},
+		}
 		runtime.global.NumberPrototype = &_object{
 			runtime:     runtime,
-			class:       "Number",
+			class:       classNumber,
 			objectClass: _classObject,
 			prototype:   runtime.global.ObjectPrototype,
 			extensible:  true,
@@ -2689,17 +2712,17 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.Number = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			value: _nativeFunctionObject{
-				name:      "Number",
+				name:      classNumber,
 				call:      builtinNumber,
 				construct: builtinNewNumber,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2713,6 +2736,13 @@ func _newContext(runtime *_runtime) {
 						value: runtime.global.NumberPrototype,
 					},
 				},
+				"isNaN": _property{
+					mode: 0101,
+					value: Value{
+						kind:  valueObject,
+						value: isNaN_function,
+					},
+				},
 				"MAX_VALUE": _property{
 					mode: 0,
 					value: Value{
@@ -2750,8 +2780,9 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
+				"isNaN",
 				"MAX_VALUE",
 				"MIN_VALUE",
 				"NaN",
@@ -2771,12 +2802,12 @@ func _newContext(runtime *_runtime) {
 	{
 		abs_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2785,7 +2816,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "abs",
@@ -2794,12 +2825,12 @@ func _newContext(runtime *_runtime) {
 		}
 		acos_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2808,7 +2839,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "acos",
@@ -2817,12 +2848,12 @@ func _newContext(runtime *_runtime) {
 		}
 		asin_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2831,7 +2862,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "asin",
@@ -2840,12 +2871,12 @@ func _newContext(runtime *_runtime) {
 		}
 		atan_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2854,7 +2885,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "atan",
@@ -2863,12 +2894,12 @@ func _newContext(runtime *_runtime) {
 		}
 		atan2_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2877,7 +2908,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "atan2",
@@ -2886,12 +2917,12 @@ func _newContext(runtime *_runtime) {
 		}
 		ceil_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2900,7 +2931,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "ceil",
@@ -2909,12 +2940,12 @@ func _newContext(runtime *_runtime) {
 		}
 		cos_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2923,7 +2954,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "cos",
@@ -2932,12 +2963,12 @@ func _newContext(runtime *_runtime) {
 		}
 		exp_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2946,7 +2977,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "exp",
@@ -2955,12 +2986,12 @@ func _newContext(runtime *_runtime) {
 		}
 		floor_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2969,7 +3000,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "floor",
@@ -2978,12 +3009,12 @@ func _newContext(runtime *_runtime) {
 		}
 		log_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -2992,7 +3023,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "log",
@@ -3001,12 +3032,12 @@ func _newContext(runtime *_runtime) {
 		}
 		max_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3015,7 +3046,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "max",
@@ -3024,12 +3055,12 @@ func _newContext(runtime *_runtime) {
 		}
 		min_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3038,7 +3069,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "min",
@@ -3047,12 +3078,12 @@ func _newContext(runtime *_runtime) {
 		}
 		pow_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3061,7 +3092,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "pow",
@@ -3070,12 +3101,12 @@ func _newContext(runtime *_runtime) {
 		}
 		random_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3084,7 +3115,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "random",
@@ -3093,12 +3124,12 @@ func _newContext(runtime *_runtime) {
 		}
 		round_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3107,7 +3138,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "round",
@@ -3116,12 +3147,12 @@ func _newContext(runtime *_runtime) {
 		}
 		sin_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3130,7 +3161,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "sin",
@@ -3139,12 +3170,12 @@ func _newContext(runtime *_runtime) {
 		}
 		sqrt_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3153,7 +3184,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "sqrt",
@@ -3162,12 +3193,12 @@ func _newContext(runtime *_runtime) {
 		}
 		tan_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3176,7 +3207,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "tan",
@@ -3406,12 +3437,12 @@ func _newContext(runtime *_runtime) {
 	{
 		toString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3420,7 +3451,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toString",
@@ -3429,12 +3460,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toDateString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3443,7 +3474,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toDateString",
@@ -3452,12 +3483,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toTimeString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3466,7 +3497,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toTimeString",
@@ -3475,12 +3506,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toUTCString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3489,7 +3520,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toUTCString",
@@ -3498,12 +3529,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toISOString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3512,7 +3543,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toISOString",
@@ -3521,12 +3552,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toJSON_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3535,7 +3566,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toJSON",
@@ -3544,12 +3575,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toGMTString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3558,7 +3589,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toGMTString",
@@ -3567,12 +3598,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toLocaleString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3581,7 +3612,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toLocaleString",
@@ -3590,12 +3621,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toLocaleDateString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3604,7 +3635,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toLocaleDateString",
@@ -3613,12 +3644,12 @@ func _newContext(runtime *_runtime) {
 		}
 		toLocaleTimeString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3627,7 +3658,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toLocaleTimeString",
@@ -3636,12 +3667,12 @@ func _newContext(runtime *_runtime) {
 		}
 		valueOf_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3650,7 +3681,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "valueOf",
@@ -3659,12 +3690,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getTime_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3673,7 +3704,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getTime",
@@ -3682,12 +3713,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getYear_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3696,7 +3727,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getYear",
@@ -3705,12 +3736,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getFullYear_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3719,7 +3750,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getFullYear",
@@ -3728,12 +3759,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getUTCFullYear_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3742,7 +3773,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getUTCFullYear",
@@ -3751,12 +3782,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getMonth_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3765,7 +3796,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getMonth",
@@ -3774,12 +3805,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getUTCMonth_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3788,7 +3819,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getUTCMonth",
@@ -3797,12 +3828,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getDate_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3811,7 +3842,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getDate",
@@ -3820,12 +3851,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getUTCDate_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3834,7 +3865,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getUTCDate",
@@ -3843,12 +3874,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getDay_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3857,7 +3888,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getDay",
@@ -3866,12 +3897,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getUTCDay_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3880,7 +3911,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getUTCDay",
@@ -3889,12 +3920,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getHours_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3903,7 +3934,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getHours",
@@ -3912,12 +3943,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getUTCHours_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3926,7 +3957,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getUTCHours",
@@ -3935,12 +3966,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getMinutes_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3949,7 +3980,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getMinutes",
@@ -3958,12 +3989,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getUTCMinutes_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3972,7 +4003,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getUTCMinutes",
@@ -3981,12 +4012,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getSeconds_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -3995,7 +4026,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getSeconds",
@@ -4004,12 +4035,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getUTCSeconds_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4018,7 +4049,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getUTCSeconds",
@@ -4027,12 +4058,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getMilliseconds_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4041,7 +4072,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getMilliseconds",
@@ -4050,12 +4081,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getUTCMilliseconds_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4064,7 +4095,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getUTCMilliseconds",
@@ -4073,12 +4104,12 @@ func _newContext(runtime *_runtime) {
 		}
 		getTimezoneOffset_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4087,7 +4118,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "getTimezoneOffset",
@@ -4096,12 +4127,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setTime_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4110,7 +4141,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setTime",
@@ -4119,12 +4150,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setMilliseconds_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4133,7 +4164,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setMilliseconds",
@@ -4142,12 +4173,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setUTCMilliseconds_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4156,7 +4187,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setUTCMilliseconds",
@@ -4165,12 +4196,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setSeconds_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4179,7 +4210,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setSeconds",
@@ -4188,12 +4219,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setUTCSeconds_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4202,7 +4233,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setUTCSeconds",
@@ -4211,12 +4242,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setMinutes_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4225,7 +4256,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setMinutes",
@@ -4234,12 +4265,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setUTCMinutes_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4248,7 +4279,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setUTCMinutes",
@@ -4257,12 +4288,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setHours_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4271,7 +4302,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setHours",
@@ -4280,12 +4311,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setUTCHours_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4294,7 +4325,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setUTCHours",
@@ -4303,12 +4334,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setDate_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4317,7 +4348,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setDate",
@@ -4326,12 +4357,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setUTCDate_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4340,7 +4371,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setUTCDate",
@@ -4349,12 +4380,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setMonth_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4363,7 +4394,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setMonth",
@@ -4372,12 +4403,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setUTCMonth_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4386,7 +4417,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setUTCMonth",
@@ -4395,12 +4426,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setYear_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4409,7 +4440,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setYear",
@@ -4418,12 +4449,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setFullYear_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4432,7 +4463,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setFullYear",
@@ -4441,12 +4472,12 @@ func _newContext(runtime *_runtime) {
 		}
 		setUTCFullYear_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4455,7 +4486,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "setUTCFullYear",
@@ -4464,12 +4495,12 @@ func _newContext(runtime *_runtime) {
 		}
 		parse_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4478,7 +4509,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "parse",
@@ -4487,12 +4518,12 @@ func _newContext(runtime *_runtime) {
 		}
 		UTC_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4501,7 +4532,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "UTC",
@@ -4510,12 +4541,12 @@ func _newContext(runtime *_runtime) {
 		}
 		now_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4524,7 +4555,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "now",
@@ -4533,7 +4564,7 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.DatePrototype = &_object{
 			runtime:     runtime,
-			class:       "Date",
+			class:       classDate,
 			objectClass: _classObject,
 			prototype:   runtime.global.ObjectPrototype,
 			extensible:  true,
@@ -4913,17 +4944,17 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.Date = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			value: _nativeFunctionObject{
-				name:      "Date",
+				name:      classDate,
 				call:      builtinDate,
 				construct: builtinNewDate,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4960,7 +4991,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 				"parse",
 				"UTC",
@@ -4979,12 +5010,12 @@ func _newContext(runtime *_runtime) {
 	{
 		toString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -4993,7 +5024,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toString",
@@ -5002,12 +5033,12 @@ func _newContext(runtime *_runtime) {
 		}
 		exec_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5016,7 +5047,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "exec",
@@ -5025,12 +5056,12 @@ func _newContext(runtime *_runtime) {
 		}
 		test_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5039,7 +5070,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "test",
@@ -5048,12 +5079,12 @@ func _newContext(runtime *_runtime) {
 		}
 		compile_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5062,7 +5093,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "compile",
@@ -5071,7 +5102,7 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.RegExpPrototype = &_object{
 			runtime:     runtime,
-			class:       "RegExp",
+			class:       classRegExp,
 			objectClass: _classObject,
 			prototype:   runtime.global.ObjectPrototype,
 			extensible:  true,
@@ -5115,17 +5146,17 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.RegExp = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			value: _nativeFunctionObject{
-				name:      "RegExp",
+				name:      classRegExp,
 				call:      builtinRegExp,
 				construct: builtinNewRegExp,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5141,7 +5172,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 			},
 		}
@@ -5157,12 +5188,12 @@ func _newContext(runtime *_runtime) {
 	{
 		toString_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5171,7 +5202,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "toString",
@@ -5180,7 +5211,7 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.ErrorPrototype = &_object{
 			runtime:     runtime,
-			class:       "Error",
+			class:       classError,
 			objectClass: _classObject,
 			prototype:   runtime.global.ObjectPrototype,
 			extensible:  true,
@@ -5197,7 +5228,7 @@ func _newContext(runtime *_runtime) {
 					mode: 0101,
 					value: Value{
 						kind:  valueString,
-						value: "Error",
+						value: classError,
 					},
 				},
 				"message": _property{
@@ -5216,17 +5247,17 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.Error = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			value: _nativeFunctionObject{
-				name:      "Error",
+				name:      classError,
 				call:      builtinError,
 				construct: builtinNewError,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5242,7 +5273,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 			},
 		}
@@ -5278,7 +5309,7 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.EvalError = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
@@ -5288,7 +5319,7 @@ func _newContext(runtime *_runtime) {
 				construct: builtinNewEvalError,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5304,7 +5335,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 			},
 		}
@@ -5340,7 +5371,7 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.TypeError = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
@@ -5350,7 +5381,7 @@ func _newContext(runtime *_runtime) {
 				construct: builtinNewTypeError,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5366,7 +5397,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 			},
 		}
@@ -5402,7 +5433,7 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.RangeError = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
@@ -5412,7 +5443,7 @@ func _newContext(runtime *_runtime) {
 				construct: builtinNewRangeError,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5428,7 +5459,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 			},
 		}
@@ -5464,7 +5495,7 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.ReferenceError = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
@@ -5474,7 +5505,7 @@ func _newContext(runtime *_runtime) {
 				construct: builtinNewReferenceError,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5490,7 +5521,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 			},
 		}
@@ -5526,7 +5557,7 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.SyntaxError = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
@@ -5536,7 +5567,7 @@ func _newContext(runtime *_runtime) {
 				construct: builtinNewSyntaxError,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5552,7 +5583,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 			},
 		}
@@ -5588,7 +5619,7 @@ func _newContext(runtime *_runtime) {
 		}
 		runtime.global.URIError = &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
@@ -5598,7 +5629,7 @@ func _newContext(runtime *_runtime) {
 				construct: builtinNewURIError,
 			},
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5614,7 +5645,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 				"prototype",
 			},
 		}
@@ -5630,12 +5661,12 @@ func _newContext(runtime *_runtime) {
 	{
 		parse_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5644,7 +5675,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "parse",
@@ -5653,12 +5684,12 @@ func _newContext(runtime *_runtime) {
 		}
 		stringify_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5667,7 +5698,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "stringify",
@@ -5705,12 +5736,12 @@ func _newContext(runtime *_runtime) {
 	{
 		eval_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5719,7 +5750,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "eval",
@@ -5728,12 +5759,12 @@ func _newContext(runtime *_runtime) {
 		}
 		parseInt_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5742,7 +5773,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "parseInt",
@@ -5751,12 +5782,12 @@ func _newContext(runtime *_runtime) {
 		}
 		parseFloat_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5765,7 +5796,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "parseFloat",
@@ -5774,12 +5805,12 @@ func _newContext(runtime *_runtime) {
 		}
 		isNaN_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5788,7 +5819,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "isNaN",
@@ -5797,12 +5828,12 @@ func _newContext(runtime *_runtime) {
 		}
 		isFinite_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5811,7 +5842,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "isFinite",
@@ -5820,12 +5851,12 @@ func _newContext(runtime *_runtime) {
 		}
 		decodeURI_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5834,7 +5865,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "decodeURI",
@@ -5843,12 +5874,12 @@ func _newContext(runtime *_runtime) {
 		}
 		decodeURIComponent_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5857,7 +5888,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "decodeURIComponent",
@@ -5866,12 +5897,12 @@ func _newContext(runtime *_runtime) {
 		}
 		encodeURI_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5880,7 +5911,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "encodeURI",
@@ -5889,12 +5920,12 @@ func _newContext(runtime *_runtime) {
 		}
 		encodeURIComponent_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5903,7 +5934,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "encodeURIComponent",
@@ -5912,12 +5943,12 @@ func _newContext(runtime *_runtime) {
 		}
 		escape_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5926,7 +5957,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "escape",
@@ -5935,12 +5966,12 @@ func _newContext(runtime *_runtime) {
 		}
 		unescape_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -5949,7 +5980,7 @@ func _newContext(runtime *_runtime) {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "unescape",
@@ -6034,42 +6065,42 @@ func _newContext(runtime *_runtime) {
 					value: unescape_function,
 				},
 			},
-			"Object": _property{
+			classObject: _property{
 				mode: 0101,
 				value: Value{
 					kind:  valueObject,
 					value: runtime.global.Object,
 				},
 			},
-			"Function": _property{
+			classFunction: _property{
 				mode: 0101,
 				value: Value{
 					kind:  valueObject,
 					value: runtime.global.Function,
 				},
 			},
-			"Array": _property{
+			classArray: _property{
 				mode: 0101,
 				value: Value{
 					kind:  valueObject,
 					value: runtime.global.Array,
 				},
 			},
-			"String": _property{
+			classString: _property{
 				mode: 0101,
 				value: Value{
 					kind:  valueObject,
 					value: runtime.global.String,
 				},
 			},
-			"Boolean": _property{
+			classBoolean: _property{
 				mode: 0101,
 				value: Value{
 					kind:  valueObject,
 					value: runtime.global.Boolean,
 				},
 			},
-			"Number": _property{
+			classNumber: _property{
 				mode: 0101,
 				value: Value{
 					kind:  valueObject,
@@ -6083,21 +6114,21 @@ func _newContext(runtime *_runtime) {
 					value: runtime.global.Math,
 				},
 			},
-			"Date": _property{
+			classDate: _property{
 				mode: 0101,
 				value: Value{
 					kind:  valueObject,
 					value: runtime.global.Date,
 				},
 			},
-			"RegExp": _property{
+			classRegExp: _property{
 				mode: 0101,
 				value: Value{
 					kind:  valueObject,
 					value: runtime.global.RegExp,
 				},
 			},
-			"Error": _property{
+			classError: _property{
 				mode: 0101,
 				value: Value{
 					kind:  valueObject,
@@ -6186,16 +6217,16 @@ func _newContext(runtime *_runtime) {
 			"encodeURIComponent",
 			"escape",
 			"unescape",
-			"Object",
-			"Function",
-			"Array",
-			"String",
-			"Boolean",
-			"Number",
+			classObject,
+			classFunction,
+			classArray,
+			classString,
+			classBoolean,
+			classNumber,
 			"Math",
-			"Date",
-			"RegExp",
-			"Error",
+			classDate,
+			classRegExp,
+			classError,
 			"EvalError",
 			"TypeError",
 			"RangeError",
@@ -6214,12 +6245,12 @@ func newConsoleObject(runtime *_runtime) *_object {
 	{
 		log_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -6228,7 +6259,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "log",
@@ -6237,12 +6268,12 @@ func newConsoleObject(runtime *_runtime) *_object {
 		}
 		debug_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -6251,7 +6282,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "debug",
@@ -6260,12 +6291,12 @@ func newConsoleObject(runtime *_runtime) *_object {
 		}
 		info_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -6274,7 +6305,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "info",
@@ -6283,12 +6314,12 @@ func newConsoleObject(runtime *_runtime) *_object {
 		}
 		error_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -6297,7 +6328,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "error",
@@ -6306,12 +6337,12 @@ func newConsoleObject(runtime *_runtime) *_object {
 		}
 		warn_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -6320,7 +6351,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "warn",
@@ -6329,12 +6360,12 @@ func newConsoleObject(runtime *_runtime) *_object {
 		}
 		dir_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -6343,7 +6374,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "dir",
@@ -6352,12 +6383,12 @@ func newConsoleObject(runtime *_runtime) *_object {
 		}
 		time_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -6366,7 +6397,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "time",
@@ -6375,12 +6406,12 @@ func newConsoleObject(runtime *_runtime) *_object {
 		}
 		timeEnd_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -6389,7 +6420,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "timeEnd",
@@ -6398,12 +6429,12 @@ func newConsoleObject(runtime *_runtime) *_object {
 		}
 		trace_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -6412,7 +6443,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "trace",
@@ -6421,12 +6452,12 @@ func newConsoleObject(runtime *_runtime) *_object {
 		}
 		assert_function := &_object{
 			runtime:     runtime,
-			class:       "Function",
+			class:       classFunction,
 			objectClass: _classObject,
 			prototype:   runtime.global.FunctionPrototype,
 			extensible:  true,
 			property: map[string]_property{
-				"length": _property{
+				propertyLength: _property{
 					mode: 0,
 					value: Value{
 						kind:  valueNumber,
@@ -6435,7 +6466,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 				},
 			},
 			propertyOrder: []string{
-				"length",
+				propertyLength,
 			},
 			value: _nativeFunctionObject{
 				name: "assert",
@@ -6444,7 +6475,7 @@ func newConsoleObject(runtime *_runtime) *_object {
 		}
 		return &_object{
 			runtime:     runtime,
-			class:       "Object",
+			class:       classObject,
 			objectClass: _classObject,
 			prototype:   runtime.global.ObjectPrototype,
 			extensible:  true,
@@ -6543,20 +6574,6 @@ func toValue_int(value int) Value {
 	}
 }
 
-func toValue_int8(value int8) Value {
-	return Value{
-		kind:  valueNumber,
-		value: value,
-	}
-}
-
-func toValue_int16(value int16) Value {
-	return Value{
-		kind:  valueNumber,
-		value: value,
-	}
-}
-
 func toValue_int32(value int32) Value {
 	return Value{
 		kind:  valueNumber,
@@ -6571,20 +6588,6 @@ func toValue_int64(value int64) Value {
 	}
 }
 
-func toValue_uint(value uint) Value {
-	return Value{
-		kind:  valueNumber,
-		value: value,
-	}
-}
-
-func toValue_uint8(value uint8) Value {
-	return Value{
-		kind:  valueNumber,
-		value: value,
-	}
-}
-
 func toValue_uint16(value uint16) Value {
 	return Value{
 		kind:  valueNumber,
@@ -6599,20 +6602,6 @@ func toValue_uint32(value uint32) Value {
 	}
 }
 
-func toValue_uint64(value uint64) Value {
-	return Value{
-		kind:  valueNumber,
-		value: value,
-	}
-}
-
-func toValue_float32(value float32) Value {
-	return Value{
-		kind:  valueNumber,
-		value: value,
-	}
-}
-
 func toValue_float64(value float64) Value {
 	return Value{
 		kind:  valueNumber,
diff --git a/inline.pl b/inline.pl
index e902904..e21444d 100755
--- a/inline.pl
+++ b/inline.pl
@@ -372,6 +372,7 @@ sub newContext {
                 1,
                 $self->functionDeclare(
                     $class,
+                    "isNaN", 1,
                 ),
                 $self->numberConstantDeclare(
                     "MAX_VALUE", "math.MaxFloat64",
diff --git a/object.go b/object.go
index 849812c..854cf52 100644
--- a/object.go
+++ b/object.go
@@ -72,7 +72,7 @@ const (
 // 8.12.8
 func (self *_object) DefaultValue(hint _defaultValueHint) Value {
 	if hint == defaultValueNoHint {
-		if self.class == "Date" {
+		if self.class == classDate {
 			// Date exception
 			hint = defaultValueHintString
 		} else {
diff --git a/otto_.go b/otto_.go
index 304a831..4d720c6 100644
--- a/otto_.go
+++ b/otto_.go
@@ -5,7 +5,6 @@ import (
 	"regexp"
 	runtime_ "runtime"
 	"strconv"
-	"strings"
 )
 
 var isIdentifier_Regexp *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z\$][a-zA-Z0-9\$]*$`)
@@ -134,16 +133,8 @@ func rangeStartLength(source []Value, size int64) (start, length int64) {
 	return
 }
 
-func boolFields(input string) (result map[string]bool) {
-	result = map[string]bool{}
-	for _, word := range strings.Fields(input) {
-		result[word] = true
-	}
-	return result
-}
-
 func hereBeDragons(arguments ...interface{}) string {
-	pc, _, _, _ := runtime_.Caller(1)
+	pc, _, _, _ := runtime_.Caller(1) // nolint: dogsled
 	name := runtime_.FuncForPC(pc).Name()
 	message := fmt.Sprintf("Here be dragons -- %s", name)
 	if len(arguments) > 0 {
@@ -159,20 +150,3 @@ func hereBeDragons(arguments ...interface{}) string {
 	}
 	return message
 }
-
-func throwHereBeDragons(arguments ...interface{}) {
-	panic(hereBeDragons(arguments...))
-}
-
-func eachPair(list []interface{}, fn func(_0, _1 interface{})) {
-	for len(list) > 0 {
-		var _0, _1 interface{}
-		_0 = list[0]
-		list = list[1:] // Pop off first
-		if len(list) > 0 {
-			_1 = list[0]
-			list = list[1:] // Pop off second
-		}
-		fn(_0, _1)
-	}
-}
diff --git a/parser/dbg.go b/parser/dbg.go
deleted file mode 100644
index 3c5f2f6..0000000
--- a/parser/dbg.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// This file was AUTOMATICALLY GENERATED by dbg-import (smuggol) for github.com/robertkrimen/dbg
-
-package parser
-
-import (
-	Dbg "github.com/robertkrimen/otto/dbg"
-)
-
-var dbg, dbgf = Dbg.New()
diff --git a/parser/error.go b/parser/error.go
index e0f74a5..084a081 100644
--- a/parser/error.go
+++ b/parser/error.go
@@ -11,7 +11,6 @@ import (
 const (
 	err_UnexpectedToken      = "Unexpected token %v"
 	err_UnexpectedEndOfInput = "Unexpected end of input"
-	err_UnexpectedEscape     = "Unexpected escape"
 )
 
 //    UnexpectedNumber:  'Unexpected number',
@@ -70,7 +69,7 @@ func (self Error) Error() string {
 }
 
 func (self *_parser) error(place interface{}, msg string, msgValues ...interface{}) *Error {
-	idx := file.Idx(0)
+	var idx file.Idx
 	switch place := place.(type) {
 	case int:
 		idx = self.idxOf(place)
@@ -120,8 +119,7 @@ func (self *_parser) errorUnexpectedToken(tkn token.Token) error {
 }
 
 // ErrorList is a list of *Errors.
-//
-type ErrorList []*Error
+type ErrorList []*Error // nolint: errname
 
 // Add adds an Error with given position and message to an ErrorList.
 func (self *ErrorList) Add(position file.Position, msg string) {
diff --git a/parser/expression.go b/parser/expression.go
index 63a169d..baaea3e 100644
--- a/parser/expression.go
+++ b/parser/expression.go
@@ -352,7 +352,7 @@ func (self *_parser) parseArrayLiteral() ast.Expression {
 	for self.token != token.RIGHT_BRACKET && self.token != token.EOF {
 		if self.token == token.COMMA {
 			// This kind of comment requires a special empty expression node.
-			empty := &ast.EmptyExpression{self.idx, self.idx}
+			empty := &ast.EmptyExpression{Begin: self.idx, End: self.idx}
 
 			if self.mode&StoreComments != 0 {
 				self.comments.SetExpression(empty)
diff --git a/parser/lexer.go b/parser/lexer.go
index d9d69e1..b66fdf5 100644
--- a/parser/lexer.go
+++ b/parser/lexer.go
@@ -628,14 +628,14 @@ func parseNumberLiteral(literal string) (value interface{}, err error) {
 	// TODO Is Uint okay? What about -MAX_UINT
 	value, err = strconv.ParseInt(literal, 0, 64)
 	if err == nil {
-		return
+		return value, nil
 	}
 
 	parseIntErr := err // Save this first error, just in case
 
 	value, err = strconv.ParseFloat(literal, 64)
 	if err == nil {
-		return
+		return value, nil
 	} else if err.(*strconv.NumError).Err == strconv.ErrRange {
 		// Infinity, etc.
 		return value, nil
@@ -651,7 +651,7 @@ func parseNumberLiteral(literal string) (value interface{}, err error) {
 			for _, chr := range literal {
 				digit := digitValue(chr)
 				if digit >= 16 {
-					goto error
+					return nil, errors.New("Illegal numeric literal")
 				}
 				value = value*16 + float64(digit)
 			}
@@ -659,7 +659,6 @@ func parseNumberLiteral(literal string) (value interface{}, err error) {
 		}
 	}
 
-error:
 	return nil, errors.New("Illegal numeric literal")
 }
 
diff --git a/parser/statement.go b/parser/statement.go
index 804cdfd..ca36666 100644
--- a/parser/statement.go
+++ b/parser/statement.go
@@ -455,7 +455,6 @@ func (self *_parser) parseWithStatement() ast.Statement {
 	self.expect(token.RIGHT_PARENTHESIS)
 
 	if self.mode&StoreComments != 0 {
-		//comments = append(comments, self.comments.FetchAll()...)
 		self.comments.CommentMap.AddComments(node, comments, ast.LEADING)
 		self.comments.CommentMap.AddComments(node, withComments, ast.WITH)
 	}
@@ -774,7 +773,6 @@ func (self *_parser) parseIfStatement() ast.Statement {
 
 func (self *_parser) parseSourceElement() ast.Statement {
 	statement := self.parseStatement()
-	//self.comments.Unset()
 	return statement
 }
 
diff --git a/property.go b/property.go
index 5445ecc..23ea258 100644
--- a/property.go
+++ b/property.go
@@ -9,7 +9,6 @@ const (
 	modeEnumerateMask               = 0070
 	modeConfigureMask               = 0007
 	modeOnMask                      = 0111
-	modeOffMask                     = 0000
 	modeSetMask                     = 0222 // If value is 2, then mode is neither "On" nor "Off"
 )
 
diff --git a/repl/autocompleter.go b/repl/autocompleter.go
index 3256678..e0b649c 100644
--- a/repl/autocompleter.go
+++ b/repl/autocompleter.go
@@ -41,7 +41,7 @@ func (a *autoCompleter) Do(line []rune, pos int) ([][]rune, int) {
 
 		if o := r.Object(); o != nil {
 			for _, v := range o.KeysByParent() {
-				l = append(l, v...)
+				l = append(l, v...) // nolint: makezero
 			}
 		}
 	}
diff --git a/result.go b/result.go
index 63642e7..4daa923 100644
--- a/result.go
+++ b/result.go
@@ -1,11 +1,9 @@
 package otto
 
-import ()
-
 type _resultKind int
 
 const (
-	resultNormal _resultKind = iota
+	_ _resultKind = iota
 	resultReturn
 	resultBreak
 	resultContinue
diff --git a/runtime.go b/runtime.go
index 9941278..5c400c6 100644
--- a/runtime.go
+++ b/runtime.go
@@ -2,6 +2,7 @@ package otto
 
 import (
 	"encoding"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"math"
@@ -264,6 +265,8 @@ func (self *_runtime) convertNumeric(v Value, t reflect.Type) reflect.Value {
 				panic(self.panicRangeError(fmt.Sprintf("converting %v to %v would overflow", val.Type(), t)))
 			}
 			return val.Convert(t)
+		case reflect.Float32, reflect.Float64:
+			return val.Convert(t)
 		}
 
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
@@ -279,20 +282,61 @@ func (self *_runtime) convertNumeric(v Value, t reflect.Type) reflect.Value {
 				panic(self.panicRangeError(fmt.Sprintf("converting %v to %v would overflow", val.Type(), t)))
 			}
 			return val.Convert(t)
+		case reflect.Float32, reflect.Float64:
+			return val.Convert(t)
+		}
+	}
+
+	panic(self.panicTypeError(fmt.Sprintf("unsupported type %v -> %v for numeric conversion", val.Type(), t)))
+}
+
+func fieldIndexByName(t reflect.Type, name string) []int {
+	for i := 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+
+		if !validGoStructName(f.Name) {
+			continue
+		}
+
+		if f.Anonymous {
+			if a := fieldIndexByName(f.Type, name); a != nil {
+				return append([]int{i}, a...)
+			}
+		}
+
+		if a := strings.SplitN(f.Tag.Get("json"), ",", 2); a[0] != "" {
+			if a[0] == "-" {
+				continue
+			}
+
+			if a[0] == name {
+				return []int{i}
+			}
+		}
+
+		if f.Name == name {
+			return []int{i}
 		}
 	}
 
-	panic(self.panicTypeError(fmt.Sprintf("unsupported type %v for numeric conversion", val.Type())))
+	return nil
 }
 
 var typeOfValue = reflect.TypeOf(Value{})
+var typeOfJSONRawMessage = reflect.TypeOf(json.RawMessage{})
 
 // convertCallParameter converts request val to type t if possible.
 // If the conversion fails due to overflow or type miss-match then it panics.
 // If no conversion is known then the original value is returned.
-func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Value {
+func (self *_runtime) convertCallParameter(v Value, t reflect.Type) (reflect.Value, error) {
 	if t == typeOfValue {
-		return reflect.ValueOf(v)
+		return reflect.ValueOf(v), nil
+	}
+
+	if t == typeOfJSONRawMessage {
+		if d, err := json.Marshal(v.export()); err == nil {
+			return reflect.ValueOf(d), nil
+		}
 	}
 
 	if v.kind == valueObject {
@@ -300,9 +344,9 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Valu
 			if gso.value.Type().AssignableTo(t) {
 				// please see TestDynamicFunctionReturningInterface for why this exists
 				if t.Kind() == reflect.Interface && gso.value.Type().ConvertibleTo(t) {
-					return gso.value.Convert(t)
+					return gso.value.Convert(t), nil
 				} else {
-					return gso.value
+					return gso.value, nil
 				}
 			}
 		}
@@ -311,70 +355,73 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Valu
 			if gao.value.Type().AssignableTo(t) {
 				// please see TestDynamicFunctionReturningInterface for why this exists
 				if t.Kind() == reflect.Interface && gao.value.Type().ConvertibleTo(t) {
-					return gao.value.Convert(t)
+					return gao.value.Convert(t), nil
 				} else {
-					return gao.value
+					return gao.value, nil
 				}
 			}
 		}
 	}
 
-	if t.Kind() == reflect.Interface {
+	tk := t.Kind()
+
+	if tk == reflect.Interface {
 		e := v.export()
 		if e == nil {
-			return reflect.Zero(t)
+			return reflect.Zero(t), nil
 		}
 		iv := reflect.ValueOf(e)
 		if iv.Type().AssignableTo(t) {
-			return iv
+			return iv, nil
 		}
 	}
 
-	tk := t.Kind()
-
 	if tk == reflect.Ptr {
 		switch v.kind {
 		case valueEmpty, valueNull, valueUndefined:
-			return reflect.Zero(t)
+			return reflect.Zero(t), nil
 		default:
 			var vv reflect.Value
-			if err := catchPanic(func() { vv = self.convertCallParameter(v, t.Elem()) }); err == nil {
-				if vv.CanAddr() {
-					return vv.Addr()
-				}
+			vv, err := self.convertCallParameter(v, t.Elem())
+			if err != nil {
+				return reflect.Zero(t), fmt.Errorf("can't convert to %s: %s", t, err.Error())
+			}
 
-				pv := reflect.New(vv.Type())
-				pv.Elem().Set(vv)
-				return pv
+			if vv.CanAddr() {
+				return vv.Addr(), nil
 			}
+
+			pv := reflect.New(vv.Type())
+			pv.Elem().Set(vv)
+			return pv, nil
 		}
 	}
 
 	switch tk {
 	case reflect.Bool:
-		return reflect.ValueOf(v.bool())
+		return reflect.ValueOf(v.bool()), nil
 	case reflect.String:
 		switch v.kind {
 		case valueString:
-			return reflect.ValueOf(v.value)
+			return reflect.ValueOf(v.value), nil
 		case valueNumber:
-			return reflect.ValueOf(fmt.Sprintf("%v", v.value))
+			return reflect.ValueOf(fmt.Sprintf("%v", v.value)), nil
 		}
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64:
 		switch v.kind {
 		case valueNumber:
-			return self.convertNumeric(v, t)
+			return self.convertNumeric(v, t), nil
 		}
 	case reflect.Slice:
 		if o := v._object(); o != nil {
-			if lv := o.get("length"); lv.IsNumber() {
+			if lv := o.get(propertyLength); lv.IsNumber() {
 				l := lv.number().int64
 
 				s := reflect.MakeSlice(t, int(l), int(l))
 
 				tt := t.Elem()
 
-				if o.class == "Array" {
+				if o.class == classArray {
 					for i := int64(0); i < l; i++ {
 						p, ok := o.property[strconv.FormatInt(i, 10)]
 						if !ok {
@@ -386,12 +433,14 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Valu
 							continue
 						}
 
-						ev := self.convertCallParameter(e, tt)
+						ev, err := self.convertCallParameter(e, tt)
+						if err != nil {
+							return reflect.Zero(t), fmt.Errorf("couldn't convert element %d of %s: %s", i, t, err.Error())
+						}
 
 						s.Index(int(i)).Set(ev)
 					}
-				} else if o.class == "GoArray" {
-
+				} else if o.class == classGoArray {
 					var gslice bool
 					switch o.value.(type) {
 					case *_goSliceObject:
@@ -416,32 +465,46 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Valu
 							continue
 						}
 
-						ev := self.convertCallParameter(e, tt)
+						ev, err := self.convertCallParameter(e, tt)
+						if err != nil {
+							return reflect.Zero(t), fmt.Errorf("couldn't convert element %d of %s: %s", i, t, err.Error())
+						}
 
 						s.Index(int(i)).Set(ev)
 					}
 				}
 
-				return s
+				return s, nil
 			}
 		}
 	case reflect.Map:
 		if o := v._object(); o != nil && t.Key().Kind() == reflect.String {
 			m := reflect.MakeMap(t)
 
+			var err error
+
 			o.enumerate(false, func(k string) bool {
-				m.SetMapIndex(reflect.ValueOf(k), self.convertCallParameter(o.get(k), t.Elem()))
+				v, verr := self.convertCallParameter(o.get(k), t.Elem())
+				if verr != nil {
+					err = fmt.Errorf("couldn't convert property %q of %s: %s", k, t, verr.Error())
+					return false
+				}
+				m.SetMapIndex(reflect.ValueOf(k), v)
 				return true
 			})
 
-			return m
+			if err != nil {
+				return reflect.Zero(t), err
+			}
+
+			return m, nil
 		}
 	case reflect.Func:
 		if t.NumOut() > 1 {
-			panic(self.panicTypeError("converting JavaScript values to Go functions with more than one return value is currently not supported"))
+			return reflect.Zero(t), fmt.Errorf("converting JavaScript values to Go functions with more than one return value is currently not supported")
 		}
 
-		if o := v._object(); o != nil && o.class == "Function" {
+		if o := v._object(); o != nil && o.class == classFunction {
 			return reflect.MakeFunc(t, func(args []reflect.Value) []reflect.Value {
 				l := make([]interface{}, len(args))
 				for i, a := range args {
@@ -459,53 +522,32 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Valu
 					return nil
 				}
 
-				return []reflect.Value{self.convertCallParameter(rv, t.Out(0))}
-			})
+				r, err := self.convertCallParameter(rv, t.Out(0))
+				if err != nil {
+					panic(self.panicTypeError(err.Error()))
+				}
+
+				return []reflect.Value{r}
+			}), nil
 		}
 	case reflect.Struct:
-		if o := v._object(); o != nil && o.class == "Object" {
+		if o := v._object(); o != nil && o.class == classObject {
 			s := reflect.New(t)
 
 			for _, k := range o.propertyOrder {
-				var f *reflect.StructField
-
-				for i := 0; i < t.NumField(); i++ {
-					ff := t.Field(i)
+				idx := fieldIndexByName(t, k)
 
-					if j := ff.Tag.Get("json"); j != "" {
-						if j == "-" {
-							continue
-						}
-
-						a := strings.Split(j, ",")
-
-						if a[0] == k {
-							f = &ff
-							break
-						}
-					}
-
-					if ff.Name == k {
-						f = &ff
-						break
-					}
-
-					if strings.EqualFold(ff.Name, k) {
-						f = &ff
-					}
-				}
-
-				if f == nil {
-					panic(self.panicTypeError("can't convert object; field %q was supplied but does not exist on target %v", k, t))
+				if idx == nil {
+					return reflect.Zero(t), fmt.Errorf("can't convert property %q of %s: field does not exist", k, t)
 				}
 
 				ss := s
 
-				for _, i := range f.Index {
+				for _, i := range idx {
 					if ss.Kind() == reflect.Ptr {
 						if ss.IsNil() {
 							if !ss.CanSet() {
-								panic(self.panicTypeError("can't set embedded pointer to unexported struct: %v", ss.Type().Elem()))
+								return reflect.Zero(t), fmt.Errorf("can't convert property %q of %s: %s is unexported", k, t, ss.Type().Elem())
 							}
 
 							ss.Set(reflect.New(ss.Type().Elem()))
@@ -517,10 +559,15 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Valu
 					ss = ss.Field(i)
 				}
 
-				ss.Set(self.convertCallParameter(o.get(k), ss.Type()))
+				v, err := self.convertCallParameter(o.get(k), ss.Type())
+				if err != nil {
+					return reflect.Zero(t), fmt.Errorf("couldn't convert property %q of %s: %s", k, t, err.Error())
+				}
+
+				ss.Set(v)
 			}
 
-			return s.Elem()
+			return s.Elem(), nil
 		}
 	}
 
@@ -529,17 +576,18 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Valu
 			if fn := o.get("toString"); fn.IsFunction() {
 				sv, err := fn.Call(v)
 				if err != nil {
-					panic(err)
+					return reflect.Zero(t), fmt.Errorf("couldn't call toString: %s", err.Error())
 				}
 
-				var r reflect.Value
-				if err := catchPanic(func() { r = self.convertCallParameter(sv, t) }); err == nil {
-					return r
+				r, err := self.convertCallParameter(sv, t)
+				if err != nil {
+					return reflect.Zero(t), fmt.Errorf("couldn't convert toString result: %s", err.Error())
 				}
+				return r, nil
 			}
 		}
 
-		return reflect.ValueOf(v.String())
+		return reflect.ValueOf(v.String()), nil
 	}
 
 	if v.kind == valueString {
@@ -549,10 +597,10 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Valu
 			r := reflect.New(t)
 
 			if err := r.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(v.string())); err != nil {
-				panic(self.panicSyntaxError("can't convert to %s: %s", t.String(), err.Error()))
+				return reflect.Zero(t), fmt.Errorf("can't convert to %s as TextUnmarshaller: %s", t.String(), err.Error())
 			}
 
-			return r.Elem()
+			return r.Elem(), nil
 		}
 	}
 
@@ -572,7 +620,7 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) reflect.Valu
 		s = v.Class()
 	}
 
-	panic(self.panicTypeError("can't convert from %q to %q", s, t.String()))
+	return reflect.Zero(t), fmt.Errorf("can't convert from %s to %s", s, t)
 }
 
 func (self *_runtime) toValue(value interface{}) Value {
@@ -677,15 +725,19 @@ func (self *_runtime) toValue(value interface{}) Value {
 						// actual set of variadic Go arguments. if that succeeds, break
 						// out of the loop.
 						if typ.IsVariadic() && len(c.ArgumentList) == nargs && i == nargs-1 {
-							var v reflect.Value
-							if err := catchPanic(func() { v = self.convertCallParameter(a, typ.In(n)) }); err == nil {
+							if v, err := self.convertCallParameter(a, typ.In(n)); err == nil {
 								in[i] = v
 								callSlice = true
 								break
 							}
 						}
 
-						in[i] = self.convertCallParameter(a, t)
+						v, err := self.convertCallParameter(a, t)
+						if err != nil {
+							panic(self.panicTypeError(err.Error()))
+						}
+
+						in[i] = v
 					}
 
 					var out []reflect.Value
diff --git a/script.go b/script.go
index 2ae890e..cfb2268 100644
--- a/script.go
+++ b/script.go
@@ -86,34 +86,27 @@ func (self *Script) marshalBinary() ([]byte, error) {
 // will return an error.
 //
 // The binary format can change at any time and should be considered unspecified and opaque.
-//
-func (self *Script) unmarshalBinary(data []byte) error {
+func (self *Script) unmarshalBinary(data []byte) (err error) {
 	decoder := gob.NewDecoder(bytes.NewReader(data))
-	err := decoder.Decode(&self.version)
-	if err != nil {
-		goto error
+	defer func() {
+		if err != nil {
+			self.version = ""
+			self.program = nil
+			self.filename = ""
+			self.src = ""
+		}
+	}()
+	if err = decoder.Decode(&self.version); err != nil {
+		return err
 	}
 	if self.version != scriptVersion {
-		err = ErrVersion
-		goto error
-	}
-	err = decoder.Decode(&self.program)
-	if err != nil {
-		goto error
+		return ErrVersion
 	}
-	err = decoder.Decode(&self.filename)
-	if err != nil {
-		goto error
+	if err = decoder.Decode(&self.program); err != nil {
+		return err
 	}
-	err = decoder.Decode(&self.src)
-	if err != nil {
-		goto error
+	if err = decoder.Decode(&self.filename); err != nil {
+		return err
 	}
-	return nil
-error:
-	self.version = ""
-	self.program = nil
-	self.filename = ""
-	self.src = ""
-	return err
+	return decoder.Decode(&self.src)
 }
diff --git a/terst/terst.go b/terst/terst.go
index a25ca8b..f026196 100644
--- a/terst/terst.go
+++ b/terst/terst.go
@@ -419,7 +419,7 @@ func typeKindString(value interface{}) string {
 
 func (scope *_scope) reset() {
 	scope.name = ""
-	scope.output = scope.output[:]
+	scope.output = scope.output[:0]
 	scope.start = time.Time{}
 	scope.duration = 0
 }
diff --git a/token/token_const.go b/token/token_const.go
index b1d83c6..738dff3 100644
--- a/token/token_const.go
+++ b/token/token_const.go
@@ -74,7 +74,7 @@ const (
 	COLON             // :
 	QUESTION_MARK     // ?
 
-	firstKeyword
+	firstKeyword // nolint: deadcode
 	IF
 	IN
 	DO
@@ -108,7 +108,7 @@ const (
 	DEBUGGER
 
 	INSTANCEOF
-	lastKeyword
+	lastKeyword // nolint: deadcode
 )
 
 var token2string = [...]string{
diff --git a/type_arguments.go b/type_arguments.go
index 841d758..0a3ddcb 100644
--- a/type_arguments.go
+++ b/type_arguments.go
@@ -20,7 +20,7 @@ func (runtime *_runtime) newArgumentsObject(indexOfParameterName []string, stash
 
 	self.prototype = runtime.global.ObjectPrototype
 
-	self.defineProperty("length", toValue_int(length), 0101, false)
+	self.defineProperty(propertyLength, toValue_int(length), 0101, false)
 
 	return self
 }
diff --git a/type_array.go b/type_array.go
index c8a974b..750c607 100644
--- a/type_array.go
+++ b/type_array.go
@@ -6,14 +6,14 @@ import (
 
 func (runtime *_runtime) newArrayObject(length uint32) *_object {
 	self := runtime.newObject()
-	self.class = "Array"
-	self.defineProperty("length", toValue_uint32(length), 0100, false)
+	self.class = classArray
+	self.defineProperty(propertyLength, toValue_uint32(length), 0100, false)
 	self.objectClass = _classArray
 	return self
 }
 
 func isArray(object *_object) bool {
-	return object != nil && (object.class == "Array" || object.class == "GoArray")
+	return object != nil && (object.class == classArray || object.class == classGoArray)
 }
 
 func objectLength(object *_object) uint32 {
@@ -21,12 +21,12 @@ func objectLength(object *_object) uint32 {
 		return 0
 	}
 	switch object.class {
-	case "Array":
-		return object.get("length").value.(uint32)
-	case "String":
-		return uint32(object.get("length").value.(int))
-	case "GoArray":
-		return uint32(object.get("length").value.(int))
+	case classArray:
+		return object.get(propertyLength).value.(uint32)
+	case classString:
+		return uint32(object.get(propertyLength).value.(int))
+	case classGoArray:
+		return uint32(object.get(propertyLength).value.(int))
 	}
 	return 0
 }
@@ -41,13 +41,13 @@ func arrayUint32(rt *_runtime, value Value) uint32 {
 }
 
 func arrayDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool {
-	lengthProperty := self.getOwnProperty("length")
+	lengthProperty := self.getOwnProperty(propertyLength)
 	lengthValue, valid := lengthProperty.value.(Value)
 	if !valid {
 		panic("Array.length != Value{}")
 	}
 	length := lengthValue.value.(uint32)
-	if name == "length" {
+	if name == propertyLength {
 		if descriptor.value == nil {
 			return objectDefineOwnProperty(self, name, descriptor, throw)
 		}
@@ -96,7 +96,7 @@ func arrayDefineOwnProperty(self *_object, name string, descriptor _property, th
 		}
 		if index >= int64(length) {
 			lengthProperty.value = toValue_uint32(uint32(index + 1))
-			objectDefineOwnProperty(self, "length", *lengthProperty, false)
+			objectDefineOwnProperty(self, propertyLength, *lengthProperty, false)
 			return true
 		}
 	}
diff --git a/type_boolean.go b/type_boolean.go
index afc45c6..9710436 100644
--- a/type_boolean.go
+++ b/type_boolean.go
@@ -1,13 +1,5 @@
 package otto
 
-import (
-	"strconv"
-)
-
 func (runtime *_runtime) newBooleanObject(value Value) *_object {
-	return runtime.newPrimitiveObject("Boolean", toValue_bool(value.bool()))
-}
-
-func booleanToString(value bool) string {
-	return strconv.FormatBool(value)
+	return runtime.newPrimitiveObject(classBoolean, toValue_bool(value.bool()))
 }
diff --git a/type_date.go b/type_date.go
index 7079e64..491cae2 100644
--- a/type_date.go
+++ b/type_date.go
@@ -84,12 +84,6 @@ func (self *_dateObject) SetTime(time Time.Time) {
 	self.Set(timeToEpoch(time))
 }
 
-func epoch2dateObject(epoch float64) _dateObject {
-	date := _dateObject{}
-	date.Set(epoch)
-	return date
-}
-
 func (self *_dateObject) Set(epoch float64) {
 	// epoch
 	self.epoch = epochToInteger(epoch)
@@ -135,7 +129,7 @@ func timeToEpoch(time Time.Time) float64 {
 
 func (runtime *_runtime) newDateObject(epoch float64) *_object {
 	self := runtime.newObject()
-	self.class = "Date"
+	self.class = classDate
 
 	// FIXME This is ugly...
 	date := _dateObject{}
@@ -150,7 +144,7 @@ func (self *_object) dateValue() _dateObject {
 }
 
 func dateObjectOf(rt *_runtime, _dateObject *_object) _dateObject {
-	if _dateObject == nil || _dateObject.class != "Date" {
+	if _dateObject == nil || _dateObject.class != classDate {
 		panic(rt.panicTypeError())
 	}
 	return _dateObject.dateValue()
@@ -165,11 +159,6 @@ func dateFromGoMonth(month Time.Month) int {
 	return int(month) - 1
 }
 
-// Both JavaScript & Go are 0-based (Sunday == 0)
-func dateToGoDay(day int) Time.Weekday {
-	return Time.Weekday(day)
-}
-
 func dateFromGoDay(day Time.Weekday) int {
 	return int(day)
 }
diff --git a/type_error.go b/type_error.go
index 84e5d79..78b4221 100644
--- a/type_error.go
+++ b/type_error.go
@@ -1,7 +1,7 @@
 package otto
 
 func (rt *_runtime) newErrorObject(name string, message Value, stackFramesToPop int) *_object {
-	self := rt.newClassObject("Error")
+	self := rt.newClassObject(classError)
 	if message.IsDefined() {
 		msg := message.string()
 		self.defineProperty("message", toValue_string(msg), 0111, false)
diff --git a/type_function.go b/type_function.go
index ad4b1f1..09285b6 100644
--- a/type_function.go
+++ b/type_function.go
@@ -6,7 +6,7 @@ type _constructFunction func(*_object, []Value) Value
 // 13.2.2 [[Construct]]
 func defaultConstruct(fn *_object, argumentList []Value) Value {
 	object := fn.runtime.newObject()
-	object.class = "Object"
+	object.class = classObject
 
 	prototype := fn.get("prototype")
 	if prototype.kind != valueObject {
@@ -38,7 +38,7 @@ type _nativeFunctionObject struct {
 }
 
 func (runtime *_runtime) _newNativeFunctionObject(name, file string, line int, native _nativeFunction, length int) *_object {
-	self := runtime.newClassObject("Function")
+	self := runtime.newClassObject(classFunction)
 	self.value = _nativeFunctionObject{
 		name:      name,
 		file:      file,
@@ -47,7 +47,7 @@ func (runtime *_runtime) _newNativeFunctionObject(name, file string, line int, n
 		construct: defaultConstruct,
 	}
 	self.defineProperty("name", toValue_string(name), 0000, false)
-	self.defineProperty("length", toValue_int(length), 0000, false)
+	self.defineProperty(propertyLength, toValue_int(length), 0000, false)
 	return self
 }
 
@@ -86,19 +86,19 @@ type _bindFunctionObject struct {
 }
 
 func (runtime *_runtime) newBoundFunctionObject(target *_object, this Value, argumentList []Value) *_object {
-	self := runtime.newClassObject("Function")
+	self := runtime.newClassObject(classFunction)
 	self.value = _bindFunctionObject{
 		target:       target,
 		this:         this,
 		argumentList: argumentList,
 	}
-	length := int(toInt32(target.get("length")))
+	length := int(toInt32(target.get(propertyLength)))
 	length -= len(argumentList)
 	if length < 0 {
 		length = 0
 	}
 	self.defineProperty("name", toValue_string("bound "+target.get("name").String()), 0000, false)
-	self.defineProperty("length", toValue_int(length), 0000, false)
+	self.defineProperty(propertyLength, toValue_int(length), 0000, false)
 	self.defineProperty("caller", Value{}, 0000, false)    // TODO Should throw a TypeError
 	self.defineProperty("arguments", Value{}, 0000, false) // TODO Should throw a TypeError
 	return self
@@ -127,13 +127,13 @@ type _nodeFunctionObject struct {
 }
 
 func (runtime *_runtime) newNodeFunctionObject(node *_nodeFunctionLiteral, stash _stash) *_object {
-	self := runtime.newClassObject("Function")
+	self := runtime.newClassObject(classFunction)
 	self.value = _nodeFunctionObject{
 		node:  node,
 		stash: stash,
 	}
 	self.defineProperty("name", toValue_string(node.name), 0000, false)
-	self.defineProperty("length", toValue_int(len(node.parameterList)), 0000, false)
+	self.defineProperty(propertyLength, toValue_int(len(node.parameterList)), 0000, false)
 	self.defineOwnProperty("caller", _property{
 		value: _propertyGetSet{
 			runtime.newNativeFunction("get", "internal", 0, func(fc FunctionCall) Value {
diff --git a/type_go_array.go b/type_go_array.go
index 13a0b10..ed8ac6a 100644
--- a/type_go_array.go
+++ b/type_go_array.go
@@ -7,7 +7,7 @@ import (
 
 func (runtime *_runtime) newGoArrayObject(value reflect.Value) *_object {
 	self := runtime.newObject()
-	self.class = "GoArray"
+	self.class = classGoArray
 	self.objectClass = _classGoArray
 	self.value = _newGoArrayObject(value)
 	return self
@@ -33,16 +33,32 @@ func _newGoArrayObject(value reflect.Value) *_goArrayObject {
 	return self
 }
 
-func (self _goArrayObject) getValue(index int64) (reflect.Value, bool) {
+func (self _goArrayObject) getValue(name string) (reflect.Value, bool) {
+	if index, err := strconv.ParseInt(name, 10, 64); err != nil {
+		v, ok := self.getValueIndex(index)
+		if ok {
+			return v, ok
+		}
+	}
+
+	if m := self.value.MethodByName(name); m != (reflect.Value{}) {
+		return m, true
+	}
+
+	return reflect.Value{}, false
+}
+
+func (self _goArrayObject) getValueIndex(index int64) (reflect.Value, bool) {
 	value := reflect.Indirect(self.value)
 	if index < int64(value.Len()) {
 		return value.Index(int(index)), true
 	}
+
 	return reflect.Value{}, false
 }
 
 func (self _goArrayObject) setValue(index int64, value Value) bool {
-	indexValue, exists := self.getValue(index)
+	indexValue, exists := self.getValueIndex(index)
 	if !exists {
 		return false
 	}
@@ -56,7 +72,7 @@ func (self _goArrayObject) setValue(index int64, value Value) bool {
 
 func goArrayGetOwnProperty(self *_object, name string) *_property {
 	// length
-	if name == "length" {
+	if name == propertyLength {
 		return &_property{
 			value: toValue(reflect.Indirect(self.value.(*_goArrayObject).value).Len()),
 			mode:  0,
@@ -64,11 +80,10 @@ func goArrayGetOwnProperty(self *_object, name string) *_property {
 	}
 
 	// .0, .1, .2, ...
-	index := stringToArrayIndex(name)
-	if index >= 0 {
+	if index := stringToArrayIndex(name); index >= 0 {
 		object := self.value.(*_goArrayObject)
 		value := Value{}
-		reflectValue, exists := object.getValue(index)
+		reflectValue, exists := object.getValueIndex(index)
 		if exists {
 			value = self.runtime.toValue(reflectValue.Interface())
 		}
@@ -78,6 +93,13 @@ func goArrayGetOwnProperty(self *_object, name string) *_property {
 		}
 	}
 
+	if method := self.value.(*_goArrayObject).value.MethodByName(name); method != (reflect.Value{}) {
+		return &_property{
+			self.runtime.toValue(method.Interface()),
+			0110,
+		}
+	}
+
 	return objectGetOwnProperty(self, name)
 }
 
@@ -96,7 +118,7 @@ func goArrayEnumerate(self *_object, all bool, each func(string) bool) {
 }
 
 func goArrayDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool {
-	if name == "length" {
+	if name == propertyLength {
 		return self.runtime.typeErrorResult(throw)
 	} else if index := stringToArrayIndex(name); index >= 0 {
 		object := self.value.(*_goArrayObject)
@@ -112,7 +134,7 @@ func goArrayDefineOwnProperty(self *_object, name string, descriptor _property,
 
 func goArrayDelete(self *_object, name string, throw bool) bool {
 	// length
-	if name == "length" {
+	if name == propertyLength {
 		return self.runtime.typeErrorResult(throw)
 	}
 
@@ -121,7 +143,7 @@ func goArrayDelete(self *_object, name string, throw bool) bool {
 	if index >= 0 {
 		object := self.value.(*_goArrayObject)
 		if object.writable {
-			indexValue, exists := object.getValue(index)
+			indexValue, exists := object.getValueIndex(index)
 			if exists {
 				indexValue.Set(reflect.Zero(reflect.Indirect(object.value).Type().Elem()))
 				return true
diff --git a/type_go_map.go b/type_go_map.go
index 41b9ac0..19fdf8a 100644
--- a/type_go_map.go
+++ b/type_go_map.go
@@ -6,7 +6,7 @@ import (
 
 func (runtime *_runtime) newGoMapObject(value reflect.Value) *_object {
 	self := runtime.newObject()
-	self.class = "Object" // TODO Should this be something else?
+	self.class = classObject // TODO Should this be something else?
 	self.objectClass = _classGoMap
 	self.value = _newGoMapObject(value)
 	return self
diff --git a/type_go_slice.go b/type_go_slice.go
index 78c69e6..f070616 100644
--- a/type_go_slice.go
+++ b/type_go_slice.go
@@ -7,7 +7,7 @@ import (
 
 func (runtime *_runtime) newGoSliceObject(value reflect.Value) *_object {
 	self := runtime.newObject()
-	self.class = "GoArray" // TODO GoSlice?
+	self.class = classGoArray // TODO GoSlice?
 	self.objectClass = _classGoSlice
 	self.value = _newGoSliceObject(value)
 	return self
@@ -46,7 +46,7 @@ func (self _goSliceObject) setValue(index int64, value Value) bool {
 
 func goSliceGetOwnProperty(self *_object, name string) *_property {
 	// length
-	if name == "length" {
+	if name == propertyLength {
 		return &_property{
 			value: toValue(self.value.(*_goSliceObject).value.Len()),
 			mode:  0,
@@ -93,7 +93,7 @@ func goSliceEnumerate(self *_object, all bool, each func(string) bool) {
 }
 
 func goSliceDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool {
-	if name == "length" {
+	if name == propertyLength {
 		return self.runtime.typeErrorResult(throw)
 	} else if index := stringToArrayIndex(name); index >= 0 {
 		if self.value.(*_goSliceObject).setValue(index, descriptor.value.(Value)) {
diff --git a/type_go_struct.go b/type_go_struct.go
index 608ac66..1388fff 100644
--- a/type_go_struct.go
+++ b/type_go_struct.go
@@ -15,7 +15,7 @@ import (
 
 func (runtime *_runtime) newGoStructObject(value reflect.Value) *_object {
 	self := runtime.newObject()
-	self.class = "Object" // TODO Should this be something else?
+	self.class = classObject // TODO Should this be something else?
 	self.objectClass = _classGoStruct
 	self.value = _newGoStructObject(value)
 	return self
@@ -36,6 +36,10 @@ func _newGoStructObject(value reflect.Value) *_goStructObject {
 }
 
 func (self _goStructObject) getValue(name string) reflect.Value {
+	if idx := fieldIndexByName(reflect.Indirect(self.value).Type(), name); len(idx) > 0 {
+		return reflect.Indirect(self.value).FieldByIndex(idx)
+	}
+
 	if validGoStructName(name) {
 		// Do not reveal hidden or unexported fields
 		if field := reflect.Indirect(self.value).FieldByName(name); (field != reflect.Value{}) {
@@ -50,25 +54,25 @@ func (self _goStructObject) getValue(name string) reflect.Value {
 	return reflect.Value{}
 }
 
-func (self _goStructObject) field(name string) (reflect.StructField, bool) {
-	return reflect.Indirect(self.value).Type().FieldByName(name)
+func (self _goStructObject) fieldIndex(name string) []int {
+	return fieldIndexByName(reflect.Indirect(self.value).Type(), name)
 }
 
 func (self _goStructObject) method(name string) (reflect.Method, bool) {
 	return reflect.Indirect(self.value).Type().MethodByName(name)
 }
 
-func (self _goStructObject) setValue(name string, value Value) bool {
-	field, exists := self.field(name)
-	if !exists {
+func (self _goStructObject) setValue(rt *_runtime, name string, value Value) bool {
+	if idx := fieldIndexByName(reflect.Indirect(self.value).Type(), name); len(idx) == 0 {
 		return false
 	}
+
 	fieldValue := self.getValue(name)
-	reflectValue, err := value.toReflectValue(field.Type.Kind())
+	converted, err := rt.convertCallParameter(value, fieldValue.Type())
 	if err != nil {
-		panic(err)
+		panic(rt.panicTypeError(err.Error()))
 	}
-	fieldValue.Set(reflectValue)
+	fieldValue.Set(converted)
 
 	return true
 }
@@ -128,7 +132,7 @@ func goStructCanPut(self *_object, name string) bool {
 
 func goStructPut(self *_object, name string, value Value, throw bool) {
 	object := self.value.(*_goStructObject)
-	if object.setValue(name, value) {
+	if object.setValue(self.runtime, name, value) {
 		return
 	}
 
diff --git a/type_number.go b/type_number.go
index 28de444..7992480 100644
--- a/type_number.go
+++ b/type_number.go
@@ -1,5 +1,5 @@
 package otto
 
 func (runtime *_runtime) newNumberObject(value Value) *_object {
-	return runtime.newPrimitiveObject("Number", value.numberValue())
+	return runtime.newPrimitiveObject(classNumber, value.numberValue())
 }
diff --git a/type_reference.go b/type_reference.go
index fd770c6..8fd23c1 100644
--- a/type_reference.go
+++ b/type_reference.go
@@ -54,15 +54,6 @@ func (self *_propertyReference) delete() bool {
 	return self.base.delete(self.name, self.strict)
 }
 
-// ArgumentReference
-
-func newArgumentReference(runtime *_runtime, base *_object, name string, strict bool, at _at) *_propertyReference {
-	if base == nil {
-		panic(hereBeDragons())
-	}
-	return newPropertyReference(runtime, base, name, strict, at)
-}
-
 type _stashReference struct {
 	name   string
 	strict bool
diff --git a/type_regexp.go b/type_regexp.go
index 57fe316..b4c0716 100644
--- a/type_regexp.go
+++ b/type_regexp.go
@@ -19,7 +19,7 @@ type _regExpObject struct {
 
 func (runtime *_runtime) newRegExpObject(pattern string, flags string) *_object {
 	self := runtime.newObject()
-	self.class = "RegExp"
+	self.class = classRegExp
 
 	global := false
 	ignoreCase := false
@@ -85,7 +85,7 @@ func (self *_object) regExpValue() _regExpObject {
 }
 
 func execRegExp(this *_object, target string) (match bool, result []int) {
-	if this.class != "RegExp" {
+	if this.class != classRegExp {
 		panic(this.runtime.panicTypeError("Calling RegExp.exec on a non-RegExp object"))
 	}
 	lastIndex := this.get("lastIndex").number().int64
@@ -99,7 +99,6 @@ func execRegExp(this *_object, target string) (match bool, result []int) {
 		result = this.regExpValue().regularExpression.FindStringSubmatchIndex(target[index:])
 	}
 	if result == nil {
-		//this.defineProperty("lastIndex", toValue_(0), 0111, true)
 		this.put("lastIndex", toValue_int(0), true)
 		return // !match
 	}
@@ -108,11 +107,12 @@ func execRegExp(this *_object, target string) (match bool, result []int) {
 	endIndex := int(lastIndex) + result[1]
 	// We do this shift here because the .FindStringSubmatchIndex above
 	// was done on a local subordinate slice of the string, not the whole string
-	for index, _ := range result {
-		result[index] += int(startIndex)
+	for index, offset := range result {
+		if offset != -1 {
+			result[index] += int(startIndex)
+		}
 	}
 	if global {
-		//this.defineProperty("lastIndex", toValue_(endIndex), 0111, true)
 		this.put("lastIndex", toValue_int(endIndex), true)
 	}
 	return // match
diff --git a/type_string.go b/type_string.go
index ef3afa4..2aa9ee9 100644
--- a/type_string.go
+++ b/type_string.go
@@ -72,8 +72,8 @@ func stringAt(str _stringObject, index int) rune {
 func (runtime *_runtime) newStringObject(value Value) *_object {
 	str := _newStringObject(value.string())
 
-	self := runtime.newClassObject("String")
-	self.defineProperty("length", toValue_int(str.Length()), 0, false)
+	self := runtime.newClassObject(classString)
+	self.defineProperty(propertyLength, toValue_int(str.Length()), 0, false)
 	self.objectClass = _classString
 	self.value = str
 	return self
diff --git a/underscore/underscore.go b/underscore/underscore.go
index 714b8f3..d5bd0ca 100644
--- a/underscore/underscore.go
+++ b/underscore/underscore.go
@@ -29,9 +29,7 @@ import (
 	"github.com/robertkrimen/otto/registry"
 )
 
-var entry *registry.Entry = registry.Register(func() string {
-	return Source()
-})
+var entry *registry.Entry = registry.Register(Source)
 
 // Enable underscore runtime inclusion.
 func Enable() {
diff --git a/value.go b/value.go
index 90c1406..8be20ef 100644
--- a/value.go
+++ b/value.go
@@ -87,11 +87,8 @@ func (value Value) IsNull() bool {
 // ---
 
 func (value Value) isCallable() bool {
-	switch value := value.value.(type) {
-	case *_object:
-		return value.isCall()
-	}
-	return false
+	v, ok := value.value.(*_object)
+	return ok && v.isCall()
 }
 
 // Call the value as a function with the given this value and argument list and
@@ -118,8 +115,7 @@ func (value Value) Call(this Value, argumentList ...interface{}) (Value, error)
 }
 
 func (value Value) call(rt *_runtime, this Value, argumentList ...interface{}) Value {
-	switch function := value.value.(type) {
-	case *_object:
+	if function, ok := value.value.(*_object); ok {
 		return function.call(this, function.runtime.toValueArray(argumentList...), false, nativeFrame)
 	}
 	if rt == nil {
@@ -137,8 +133,7 @@ func (value Value) constructSafe(rt *_runtime, this Value, argumentList ...inter
 }
 
 func (value Value) construct(rt *_runtime, this Value, argumentList ...interface{}) Value {
-	switch fn := value.value.(type) {
-	case *_object:
+	if fn, ok := value.value.(*_object); ok {
 		return fn.construct(fn.runtime.toValueArray(argumentList...))
 	}
 	if rt == nil {
@@ -193,7 +188,7 @@ func (value Value) IsFunction() bool {
 	if value.kind != valueObject {
 		return false
 	}
-	return value.value.(*_object).class == "Function"
+	return value.value.(*_object).class == classFunction
 }
 
 // Class will return the class string of the value or the empty string if value is not an object.
@@ -227,42 +222,42 @@ func (value Value) isStringObject() bool {
 	if value.kind != valueObject {
 		return false
 	}
-	return value.value.(*_object).class == "String"
+	return value.value.(*_object).class == classString
 }
 
 func (value Value) isBooleanObject() bool {
 	if value.kind != valueObject {
 		return false
 	}
-	return value.value.(*_object).class == "Boolean"
+	return value.value.(*_object).class == classBoolean
 }
 
 func (value Value) isNumberObject() bool {
 	if value.kind != valueObject {
 		return false
 	}
-	return value.value.(*_object).class == "Number"
+	return value.value.(*_object).class == classNumber
 }
 
 func (value Value) isDate() bool {
 	if value.kind != valueObject {
 		return false
 	}
-	return value.value.(*_object).class == "Date"
+	return value.value.(*_object).class == classDate
 }
 
 func (value Value) isRegExp() bool {
 	if value.kind != valueObject {
 		return false
 	}
-	return value.value.(*_object).class == "RegExp"
+	return value.value.(*_object).class == classRegExp
 }
 
 func (value Value) isError() bool {
 	if value.kind != valueObject {
 		return false
 	}
-	return value.value.(*_object).class == "Error"
+	return value.value.(*_object).class == classError
 }
 
 // ---
@@ -461,9 +456,8 @@ func (value Value) ToString() (string, error) {
 }
 
 func (value Value) _object() *_object {
-	switch value := value.value.(type) {
-	case *_object:
-		return value
+	if v, ok := value.value.(*_object); ok {
+		return v
 	}
 	return nil
 }
@@ -472,24 +466,21 @@ func (value Value) _object() *_object {
 //
 // This method will not do any implicit conversion. For example, calling this method on a string primitive value will not return a String object.
 func (value Value) Object() *Object {
-	switch object := value.value.(type) {
-	case *_object:
+	if object, ok := value.value.(*_object); ok {
 		return _newObject(object, value)
 	}
 	return nil
 }
 
 func (value Value) reference() _reference {
-	switch value := value.value.(type) {
-	case _reference:
+	if value, ok := value.value.(_reference); ok {
 		return value
 	}
 	return nil
 }
 
 func (value Value) resolve() Value {
-	switch value := value.value.(type) {
-	case _reference:
+	if value, ok := value.value.(_reference); ok {
 		return value.getValue()
 	}
 	return value
@@ -503,14 +494,6 @@ var (
 	__NegativeZero__     float64 = math.Float64frombits(0 | (1 << 63))
 )
 
-func positiveInfinity() float64 {
-	return __PositiveInfinity__
-}
-
-func negativeInfinity() float64 {
-	return __NegativeInfinity__
-}
-
 func positiveZero() float64 {
 	return __PositiveZero__
 }
@@ -569,62 +552,60 @@ func sameValue(x Value, y Value) bool {
 	if x.kind != y.kind {
 		return false
 	}
-	result := false
+
 	switch x.kind {
 	case valueUndefined, valueNull:
-		result = true
+		return true
 	case valueNumber:
 		x := x.float64()
 		y := y.float64()
 		if math.IsNaN(x) && math.IsNaN(y) {
-			result = true
-		} else {
-			result = x == y
-			if result && x == 0 {
+			return true
+		}
+
+		if x == y {
+			if x == 0 {
 				// Since +0 != -0
-				result = math.Signbit(x) == math.Signbit(y)
+				return math.Signbit(x) == math.Signbit(y)
 			}
+			return true
 		}
+		return false
 	case valueString:
-		result = x.string() == y.string()
+		return x.string() == y.string()
 	case valueBoolean:
-		result = x.bool() == y.bool()
+		return x.bool() == y.bool()
 	case valueObject:
-		result = x._object() == y._object()
+		return x._object() == y._object()
 	default:
 		panic(hereBeDragons())
 	}
-
-	return result
 }
 
 func strictEqualityComparison(x Value, y Value) bool {
 	if x.kind != y.kind {
 		return false
 	}
-	result := false
+
 	switch x.kind {
 	case valueUndefined, valueNull:
-		result = true
+		return true
 	case valueNumber:
 		x := x.float64()
 		y := y.float64()
 		if math.IsNaN(x) && math.IsNaN(y) {
-			result = false
-		} else {
-			result = x == y
+			return false
 		}
+		return x == y
 	case valueString:
-		result = x.string() == y.string()
+		return x.string() == y.string()
 	case valueBoolean:
-		result = x.bool() == y.bool()
+		return x.bool() == y.bool()
 	case valueObject:
-		result = x._object() == y._object()
+		return x._object() == y._object()
 	default:
 		panic(hereBeDragons())
 	}
-
-	return result
 }
 
 // Export will attempt to convert the value to a Go representation
@@ -676,9 +657,9 @@ func (self Value) export() interface{} {
 		case *_goSliceObject:
 			return value.value.Interface()
 		}
-		if object.class == "Array" {
+		if object.class == classArray {
 			result := make([]interface{}, 0)
-			lengthValue := object.get("length")
+			lengthValue := object.get(propertyLength)
 			length := lengthValue.value.(uint32)
 			kind := reflect.Invalid
 			state := 0
diff --git a/value_number.go b/value_number.go
index 8cbf136..649fc68 100644
--- a/value_number.go
+++ b/value_number.go
@@ -85,37 +85,17 @@ func (value Value) float64() float64 {
 }
 
 const (
-	float_2_64   float64 = 18446744073709551616.0
-	float_2_63   float64 = 9223372036854775808.0
-	float_2_32   float64 = 4294967296.0
-	float_2_31   float64 = 2147483648.0
-	float_2_16   float64 = 65536.0
-	integer_2_32 int64   = 4294967296
-	integer_2_31 int64   = 2146483648
-	sqrt1_2      float64 = math.Sqrt2 / 2
+	float_2_32 float64 = 4294967296.0
+	float_2_31 float64 = 2147483648.0
+	float_2_16 float64 = 65536.0
+	sqrt1_2    float64 = math.Sqrt2 / 2
 )
 
 const (
-	maxInt8   = math.MaxInt8
-	minInt8   = math.MinInt8
-	maxInt16  = math.MaxInt16
-	minInt16  = math.MinInt16
-	maxInt32  = math.MaxInt32
-	minInt32  = math.MinInt32
-	maxInt64  = math.MaxInt64
-	minInt64  = math.MinInt64
-	maxUint8  = math.MaxUint8
-	maxUint16 = math.MaxUint16
 	maxUint32 = math.MaxUint32
-	maxUint64 = math.MaxUint64
-	maxUint   = ^uint(0)
-	minUint   = 0
 	maxInt    = int(^uint(0) >> 1)
-	minInt    = -maxInt - 1
 
 	// int64
-	int64_maxInt    int64 = int64(maxInt)
-	int64_minInt    int64 = int64(minInt)
 	int64_maxInt8   int64 = math.MaxInt8
 	int64_minInt8   int64 = math.MinInt8
 	int64_maxInt16  int64 = math.MaxInt16
@@ -129,9 +109,7 @@ const (
 	// float64
 	float_maxInt    float64 = float64(int(^uint(0) >> 1))
 	float_minInt    float64 = float64(int(-maxInt - 1))
-	float_minUint   float64 = float64(0)
 	float_maxUint   float64 = float64(uint(^uint(0)))
-	float_minUint64 float64 = float64(0)
 	float_maxUint64 float64 = math.MaxUint64
 	float_maxInt64  float64 = math.MaxInt64
 	float_minInt64  float64 = math.MinInt64
@@ -220,7 +198,7 @@ func (value Value) number() (number _number) {
 		return
 	}
 
-	integer := float64(0)
+	var integer float64
 	if float > 0 {
 		integer = math.Floor(float)
 	} else {
diff --git a/value_primitive.go b/value_primitive.go
index 11ed329..e76147c 100644
--- a/value_primitive.go
+++ b/value_primitive.go
@@ -1,9 +1,5 @@
 package otto
 
-func toStringPrimitive(value Value) Value {
-	return _toPrimitive(value, defaultValueHintString)
-}
-
 func toNumberPrimitive(value Value) Value {
 	return _toPrimitive(value, defaultValueHintNumber)
 }


Test patch:
diff --git a/.github/workflows/test-lint.yml b/.github/workflows/test-lint.yml
new file mode 100644
index 0000000..3afd8c9
--- /dev/null
+++ b/.github/workflows/test-lint.yml
@@ -0,0 +1,24 @@
+name: Go test and lint
+
+on:
+  push:
+    branches: '**'
+
+jobs:
+  go-test-lint:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Set up Go
+        uses: actions/setup-go@v2
+        with:
+          go-version: 1.17
+
+      - name: Test
+        run: go test -v ./...
+
+      - name: golangci-lint
+        uses: golangci/golangci-lint-action@v2
+        with:
+          version: latest
diff --git a/ast/comments_test.go b/ast/comments_test.go
index 86d41b1..bc4bbda 100644
--- a/ast/comments_test.go
+++ b/ast/comments_test.go
@@ -1,8 +1,9 @@
 package ast
 
 import (
-	"github.com/robertkrimen/otto/file"
 	"testing"
+
+	"github.com/robertkrimen/otto/file"
 )
 
 func TestCommentMap(t *testing.T) {
diff --git a/builtin_test.go b/builtin_test.go
index f5be00a..dd76dcd 100644
--- a/builtin_test.go
+++ b/builtin_test.go
@@ -134,3 +134,14 @@ func TestGlobal_unescape(t *testing.T) {
         `, "abc,==,abc=%+32,世界")
 	})
 }
+
+func TestNumber_isNaN(t *testing.T) {
+	tt(t, func() {
+		test, _ := test()
+		test(`Number.isNaN(1)`, false)
+		test(`Number.isNaN(null)`, false)
+		test(`Number.isNaN()`, false)
+		test(`Number.isNaN(Number.NaN)`, true)
+		test(`Number.isNaN(0+undefined)`, true)
+	})
+}
diff --git a/call_test.go b/call_test.go
index d1f687a..349696a 100644
--- a/call_test.go
+++ b/call_test.go
@@ -5,6 +5,10 @@ import (
 	"testing"
 )
 
+const (
+	testAb = "ab"
+)
+
 func BenchmarkNativeCallWithString(b *testing.B) {
 	vm := New()
 	vm.Set("x", func(a1 string) {})
@@ -1405,7 +1409,7 @@ func TestNativeCallMethodWithStruct(t *testing.T) {
 	vm.Set("x", testNativeCallWithStruct{Prefix: "a"})
 
 	vm.Set("t", func(s string) {
-		if s != "ab" {
+		if s != testAb {
 			t.Fail()
 		}
 
@@ -1432,7 +1436,7 @@ func TestNativeCallPointerMethodWithStruct(t *testing.T) {
 	vm.Set("x", &testNativeCallWithStruct{Prefix: "a"})
 
 	vm.Set("t", func(s string) {
-		if s != "ab" {
+		if s != testAb {
 			t.Fail()
 		}
 
@@ -1459,7 +1463,7 @@ func TestNativeCallMethodWithStructPointer(t *testing.T) {
 	vm.Set("x", testNativeCallWithStruct{Prefix: "a"})
 
 	vm.Set("t", func(s string) {
-		if s != "ab" {
+		if s != testAb {
 			t.Fail()
 		}
 
@@ -1486,7 +1490,7 @@ func TestNativeCallPointerMethodWithStructPointer(t *testing.T) {
 	vm.Set("x", &testNativeCallWithStruct{Prefix: "a"})
 
 	vm.Set("t", func(s string) {
-		if s != "ab" {
+		if s != testAb {
 			t.Fail()
 		}
 
diff --git a/documentation_test.go b/documentation_test.go
index 0464611..4e453f7 100644
--- a/documentation_test.go
+++ b/documentation_test.go
@@ -4,8 +4,7 @@ import (
 	"fmt"
 )
 
-func ExampleSynopsis() {
-
+func ExampleSynopsis() { // nolint: govet
 	vm := New()
 	vm.Run(`
         abc = 2 + 2;
@@ -70,8 +69,7 @@ func ExampleSynopsis() {
 	// 4
 }
 
-func ExampleConsole() {
-
+func ExampleConsole() { // nolint: govet
 	vm := New()
 	console := map[string]interface{}{
 		"log": func(call FunctionCall) Value {
@@ -81,10 +79,11 @@ func ExampleConsole() {
 	}
 
 	err := vm.Set("console", console)
+	if err != nil {
+		panic(fmt.Errorf("console error: %w", err))
+	}
 
-	value, err := vm.Run(`
-        console.log("Hello, World.");
-    `)
+	value, err := vm.Run(`console.log("Hello, World.");`)
 	fmt.Println(value)
 	fmt.Println(err)
 
diff --git a/error_test.go b/error_test.go
index d44fedf..4451c97 100644
--- a/error_test.go
+++ b/error_test.go
@@ -272,7 +272,7 @@ func TestMakeCustomErrorReturn(t *testing.T) {
 			panic(err)
 		}
 
-		is(v.Class(), "Error")
+		is(v.Class(), classError)
 
 		name, err := v.Object().Get("name")
 		if err != nil {
@@ -306,8 +306,6 @@ func TestMakeCustomError(t *testing.T) {
 
 		vm.Set("A", func(c FunctionCall) Value {
 			panic(vm.MakeCustomError("CarrotError", "carrots is life, carrots is love"))
-
-			return UndefinedValue()
 		})
 
 		s, _ := vm.Compile("test.js", `
@@ -354,8 +352,6 @@ func TestMakeTypeError(t *testing.T) {
 
 		vm.Set("A", func(c FunctionCall) Value {
 			panic(vm.MakeTypeError("these aren't my glasses"))
-
-			return UndefinedValue()
 		})
 
 		s, _ := vm.Compile("test.js", `
@@ -388,8 +384,6 @@ func TestMakeRangeError(t *testing.T) {
 
 		vm.Set("A", func(c FunctionCall) Value {
 			panic(vm.MakeRangeError("too many"))
-
-			return UndefinedValue()
 		})
 
 		s, _ := vm.Compile("test.js", `
@@ -422,8 +416,6 @@ func TestMakeSyntaxError(t *testing.T) {
 
 		vm.Set("A", func(c FunctionCall) Value {
 			panic(vm.MakeSyntaxError("i think you meant \"you're\""))
-
-			return UndefinedValue()
 		})
 
 		s, _ := vm.Compile("test.js", `
diff --git a/functional_benchmark_test.go b/functional_benchmark_test.go
index 079b11e..fa51cc2 100644
--- a/functional_benchmark_test.go
+++ b/functional_benchmark_test.go
@@ -8,23 +8,23 @@ import (
 )
 
 func TestGoSliceQuickSort(t *testing.T) {
-	testGoSliceSort("quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort, t)
+	testGoSliceSort(t, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort)
 }
 
 func TestGoSliceHeapSort(t *testing.T) {
-	testGoSliceSort("heapSort(testSlice)", jsHeapSort, t)
+	testGoSliceSort(t, "heapSort(testSlice)", jsHeapSort)
 }
 
 func TestJsArrayQuicksort(t *testing.T) {
-	testJsArraySort("quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort, t)
+	testJsArraySort(t, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort)
 }
 
 func TestJsArrayHeapSort(t *testing.T) {
-	testJsArraySort("heapSort(testSlice)", jsHeapSort, t)
+	testJsArraySort(t, "heapSort(testSlice)", jsHeapSort)
 }
 
 func TestJsArrayMergeSort(t *testing.T) {
-	testJsArraySort("testSlice = mergeSort(testSlice)", jsMergeSort, t)
+	testJsArraySort(t, "testSlice = mergeSort(testSlice)", jsMergeSort)
 }
 
 func TestCryptoAes(t *testing.T) {
@@ -36,27 +36,26 @@ func TestCryptoAes(t *testing.T) {
 }
 
 func BenchmarkGoSliceQuickSort100000000(b *testing.B) {
-	benchmarkGoSliceSort(100000000, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort, b)
+	benchmarkGoSliceSort(b, 100000000, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort)
 }
 
 func BenchmarkGoSliceHeapSort100000000(b *testing.B) {
-	benchmarkGoSliceSort(100000000, "heapSort(testSlice);", jsHeapSort, b)
+	benchmarkGoSliceSort(b, 100000000, "heapSort(testSlice);", jsHeapSort)
 }
 
 func BenchmarkJsArrayQuickSort10000(b *testing.B) {
-	benchmarkJsArraySort(10000, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort, b)
+	benchmarkJsArraySort(b, 10000, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort)
 }
 
 func BenchmarkJsArrayMergeSort10000(b *testing.B) {
-	benchmarkJsArraySort(10000, "mergeSort(testSlice);", jsMergeSort, b)
+	benchmarkJsArraySort(b, 10000, "mergeSort(testSlice);", jsMergeSort)
 }
 
 func BenchmarkJsArrayHeapSort10000(b *testing.B) {
-	benchmarkJsArraySort(10000, "heapSort(testSlice);", jsHeapSort, b)
+	benchmarkJsArraySort(b, 10000, "heapSort(testSlice);", jsHeapSort)
 }
 
 func BenchmarkCryptoAES(b *testing.B) {
-
 	vm := New()
 
 	// Make sure VM creation time is not counted in runtime test
@@ -67,7 +66,8 @@ func BenchmarkCryptoAES(b *testing.B) {
 	}
 }
 
-func testGoSliceSort(sortFuncCall string, sortCode string, t *testing.T) {
+func testGoSliceSort(t *testing.T, sortFuncCall string, sortCode string) {
+	t.Helper()
 	tt(t, func() {
 		test, vm := test()
 
@@ -94,7 +94,8 @@ func testGoSliceSort(sortFuncCall string, sortCode string, t *testing.T) {
 	})
 }
 
-func testJsArraySort(sortFuncCall string, sortCode string, t *testing.T) {
+func testJsArraySort(t *testing.T, sortFuncCall string, sortCode string) {
+	t.Helper()
 	tt(t, func() {
 		test, vm := test()
 
@@ -113,7 +114,8 @@ func testJsArraySort(sortFuncCall string, sortCode string, t *testing.T) {
 	})
 }
 
-func benchmarkGoSliceSort(size int, sortFuncCall string, sortCode string, b *testing.B) {
+func benchmarkGoSliceSort(b *testing.B, size int, sortFuncCall string, sortCode string) {
+	b.Helper()
 	// generate arbitrary slice of 'size'
 	testSlice := make([]int, size)
 	for i := 0; i < size; i++ {
@@ -133,7 +135,8 @@ func benchmarkGoSliceSort(size int, sortFuncCall string, sortCode string, b *tes
 	}
 }
 
-func benchmarkJsArraySort(size int, sortFuncCall string, sortCode string, b *testing.B) {
+func benchmarkJsArraySort(b *testing.B, size int, sortFuncCall string, sortCode string) {
+	b.Helper()
 	// generate arbitrary slice of 'size'
 	testSlice := make([]string, size)
 	for i, _ := range testSlice {
diff --git a/global_test.go b/global_test.go
index 9257b58..37168d3 100644
--- a/global_test.go
+++ b/global_test.go
@@ -33,7 +33,7 @@ func TestGlobal(t *testing.T) {
 
 			// FIXME enterGlobalScope
 			if false {
-				value := runtime.scope.lexical.getBinding("Object", false)._object().call(UndefinedValue(), []Value{toValue(runtime.newObject())}, false, nativeFrame)
+				value := runtime.scope.lexical.getBinding(classObject, false)._object().call(UndefinedValue(), []Value{toValue(runtime.newObject())}, false, nativeFrame)
 				is(value.IsObject(), true)
 				is(value, "[object Object]")
 				is(value._object().prototype == runtime.global.ObjectPrototype, true)
@@ -51,16 +51,16 @@ func TestGlobal(t *testing.T) {
 				is(call(value, "propertyIsEnumerable", "xyzzy"), true)
 				is(value._object().get("xyzzy"), "Nothing happens.")
 
-				is(call(runtime.scope.lexical.getBinding("Object", false), "isPrototypeOf", value), false)
-				is(call(runtime.scope.lexical.getBinding("Object", false)._object().get("prototype"), "isPrototypeOf", value), true)
-				is(call(runtime.scope.lexical.getBinding("Function", false), "isPrototypeOf", value), false)
+				is(call(runtime.scope.lexical.getBinding(classObject, false), "isPrototypeOf", value), false)
+				is(call(runtime.scope.lexical.getBinding(classObject, false)._object().get("prototype"), "isPrototypeOf", value), true)
+				is(call(runtime.scope.lexical.getBinding(classFunction, false), "isPrototypeOf", value), false)
 
 				is(runtime.newObject().prototype == runtime.global.Object.get("prototype")._object(), true)
 
 				abc := runtime.newBoolean(toValue_bool(true))
 				is(toValue_object(abc), "true") // TODO Call primitive?
 
-				//def := runtime.localGet("Boolean")._object().Construct(UndefinedValue(), []Value{})
+				//def := runtime.localGet(classBoolean)._object().Construct(UndefinedValue(), []Value{})
 				//is(def, "false") // TODO Call primitive?
 			}
 		}
diff --git a/otto_test.go b/otto_test.go
index ad70a75..cdbf95c 100644
--- a/otto_test.go
+++ b/otto_test.go
@@ -1326,6 +1326,7 @@ func TestOttoCall_clone(t *testing.T) {
 			value, err := vm2.Run(`
                 [ abc.toString(), def.toString() ];
             `)
+			is(err, nil)
 			is(value, `function() { return "abc"; },function() { return "def"; }`)
 
 			_, err = vm2.Run(`
@@ -1336,11 +1337,13 @@ func TestOttoCall_clone(t *testing.T) {
 			value, err = vm1.Run(`
                 [ abc.toString(), def.toString() ];
             `)
+			is(err, nil)
 			is(value, `function() { return "abc"; },function() { return "def"; }`)
 
 			value, err = vm2.Run(`
                 [ abc.toString(), def.toString() ];
             `)
+			is(err, nil)
 			is(value, `function() { return "abc"; },function() { return "ghi"; }`)
 		}
 
@@ -1367,6 +1370,7 @@ func TestOttoRun(t *testing.T) {
 		is(value, 4)
 
 		program, err = parser.ParseFile(nil, "", "var abc; if (!abc) abc = 0; abc += 2; abc;", 0)
+		is(err, nil)
 		value, err = vm.Run(program)
 		is(err, nil)
 		is(value, 2)
@@ -1494,7 +1498,7 @@ func TestOttoContext(t *testing.T) {
 	builtins := []string{
 		"escape",
 		"URIError",
-		"RegExp",
+		classRegExp,
 		"ReferenceError",
 		"parseFloat",
 		"parseInt",
@@ -1506,23 +1510,23 @@ func TestOttoContext(t *testing.T) {
 		"isNaN",
 		"unescape",
 		"decodeURI",
-		"Object",
-		"Function",
+		classObject,
+		classFunction,
 		"RangeError",
-		"Error",
+		classError,
 		"get_context",
 		"eval",
-		"Number",
+		classNumber,
 		"Math",
 		"NaN",
-		"Date",
-		"Boolean",
+		classDate,
+		classBoolean,
 		"console",
 		"encodeURI",
 		"EvalError",
-		"Array",
+		classArray,
 		"TypeError",
-		"String",
+		classString,
 		"isFinite",
 		"undefined",
 	}
diff --git a/parser/comments_test.go b/parser/comments_test.go
index 72d08bb..7fa65c7 100644
--- a/parser/comments_test.go
+++ b/parser/comments_test.go
@@ -2,9 +2,10 @@ package parser
 
 import (
 	"fmt"
-	"github.com/robertkrimen/otto/ast"
 	"reflect"
 	"testing"
+
+	"github.com/robertkrimen/otto/ast"
 )
 
 func checkComments(actual []*ast.Comment, expected []string, position ast.CommentPosition) error {
@@ -31,13 +32,6 @@ func checkComments(actual []*ast.Comment, expected []string, position ast.Commen
 	return nil
 }
 
-func displayStatements(statements []ast.Statement) {
-	fmt.Printf("Printing statements (%v)\n", len(statements))
-	for k, v := range statements {
-		fmt.Printf("Type of line %v: %v\n", k, reflect.TypeOf(v))
-	}
-}
-
 func displayComments(m ast.CommentMap) {
 	fmt.Printf("Displaying comments:\n")
 	for n, comments := range m {
@@ -404,7 +398,7 @@ t2 = "Nothing happens."
 		is(checkComments((parser.comments.CommentMap)[program.Body[1]], []string{"Test", "Test2"}, ast.LEADING), nil)
 
 		// Misc
-		parser, program = test(`
+		parser, _ = test(`
 var x = Object.create({y: {
 },
 // a
@@ -413,7 +407,7 @@ var x = Object.create({y: {
 		is(parser.comments.CommentMap.Size(), 1)
 
 		// Misc 2
-		parser, program = test(`
+		parser, _ = test(`
 var x = Object.create({y: {
 },
 // a
@@ -818,7 +812,7 @@ if(a) {
 		is(checkComments((parser.comments.CommentMap)[program.Body[0].(*ast.IfStatement).Alternate], []string{"comment"}, ast.TRAILING), nil)
 
 		// If then else pt 8
-		parser, program = test(`
+		parser, _ = test(`
 if
 /*comment*/
 (a) {
@@ -830,7 +824,7 @@ if
 		is(parser.comments.CommentMap.Size(), 1)
 
 		// If then else pt 9
-		parser, program = test(`
+		parser, _ = test(`
 if
 (a)
  /*comment*/{
@@ -842,7 +836,7 @@ if
 		is(parser.comments.CommentMap.Size(), 1)
 
 		// If then else pt 10
-		parser, program = test(`
+		parser, _ = test(`
 if(a){
 	b
 }
@@ -971,7 +965,7 @@ while(a) {
 		is(checkComments((parser.comments.CommentMap)[program.Body[0].(*ast.WhileStatement).Body.(*ast.BlockStatement)], []string{"comment"}, ast.FINAL), nil)
 
 		// While pt 8
-		parser, program = test(`
+		parser, _ = test(`
 while
 /*comment*/(a) {
 
@@ -980,7 +974,7 @@ while
 		is(parser.comments.CommentMap.Size(), 1)
 
 		// While pt 9
-		parser, program = test(`
+		parser, _ = test(`
 while
 (a)
  /*comment*/{
@@ -1109,7 +1103,7 @@ with(a)  {
 		is(checkComments((parser.comments.CommentMap)[program.Body[0].(*ast.WithStatement).Body], []string{"comment"}, ast.TRAILING), nil)
 
 		// With pt 7
-		parser, program = test(`
+		parser, _ = test(`
 with
 /*comment*/(a)  {
 }
@@ -1117,7 +1111,7 @@ with
 		is(parser.comments.CommentMap.Size(), 1)
 
 		// With pt 8
-		parser, program = test(`
+		parser, _ = test(`
 with
 (a)
   /*comment*/{
@@ -1176,7 +1170,7 @@ var a, b;
 		is(checkComments((parser.comments.CommentMap)[program], []string{"comment"}, ast.TRAILING), nil)
 
 		// Return
-		parser, program = test(`
+		parser, _ = test(`
 		function f() {
 /*comment*/return o
 }
@@ -1356,7 +1350,7 @@ try {
 		is(checkComments((parser.comments.CommentMap)[program.Body[0].(*ast.TryStatement).Finally], []string{"comment"}, ast.LEADING), nil)
 
 		// Switch / comment
-		parser, program = test(`
+		parser, _ = test(`
 var volvo = 1
 //comment
 switch(abra) {
@@ -1365,7 +1359,7 @@ switch(abra) {
 		is(parser.comments.CommentMap.Size(), 1)
 
 		// Switch / comment
-		parser, program = test(`
+		parser, _ = test(`
 f("string",{
    key: "val"
    //comment
diff --git a/parser/marshal_test.go b/parser/marshal_test.go
index f54cd2d..4219bfe 100644
--- a/parser/marshal_test.go
+++ b/parser/marshal_test.go
@@ -854,8 +854,6 @@ func TestParserAST(t *testing.T) {
 ]
             `)
 
-		return
-
 		test(`
         if (!abc && abc.jkl(def) && abc[0] === +abc[0] && abc.length < ghi) {
         }
diff --git a/parser/parser_test.go b/parser/parser_test.go
index 6cc8f99..40b3204 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -98,9 +98,9 @@ func TestParserErr(t *testing.T) {
 			return program, parser
 		}
 
-		program, parser := test("", nil)
+		test("", nil)
 
-		program, parser = test(`
+		program, parser := test(`
         var abc;
         break; do {
         } while(true);
@@ -523,7 +523,7 @@ func TestParser(t *testing.T) {
             abc()
         `, nil)
 
-		program := test("", nil)
+		test("", nil)
 
 		test("//", nil)
 
@@ -541,7 +541,7 @@ func TestParser(t *testing.T) {
 
 		test("new +", "(anonymous): Line 1:5 Unexpected token +")
 
-		program = test(";", nil)
+		program := test(";", nil)
 		is(len(program.Body), 1)
 		is(program.Body[0].(*ast.EmptyStatement).Semicolon, file.Idx(1))
 
@@ -1012,6 +1012,7 @@ func TestPosition(t *testing.T) {
 
 		parser = _newParser("", "this.style", 1, nil)
 		program, err = parser.parse()
+		is(err, nil)
 		node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.DotExpression).Left.(*ast.ThisExpression)
 		is(node.Idx0(), file.Idx(1))
 		is(node.Idx1(), file.Idx(5))
diff --git a/reflect_test.go b/reflect_test.go
index 5b654e9..38b622b 100644
--- a/reflect_test.go
+++ b/reflect_test.go
@@ -1,6 +1,8 @@
 package otto
 
 import (
+	"bytes"
+	"encoding/json"
 	"fmt"
 	"math"
 	"reflect"
@@ -759,11 +761,11 @@ func TestPassthrough(t *testing.T) {
 	})
 }
 
-type TestDynamicFunctionReturningInterface_MyStruct1 struct{}
+type TestDynamicFunctionReturningInterface_MyStruct1 struct{} // nolint: errname
 
 func (m *TestDynamicFunctionReturningInterface_MyStruct1) Error() string { return "MyStruct1" }
 
-type TestDynamicFunctionReturningInterface_MyStruct2 struct{}
+type TestDynamicFunctionReturningInterface_MyStruct2 struct{} // nolint: errname
 
 func (m *TestDynamicFunctionReturningInterface_MyStruct2) Error() string { return "MyStruct2" }
 
@@ -880,3 +882,56 @@ func TestTextUnmarshallerCallParameterConversion(t *testing.T) {
 		}
 	})
 }
+
+func TestJSONRawMessageCallParameterConversion(t *testing.T) {
+	for _, e := range []struct {
+		c string
+		r string
+		e bool
+	}{
+		{"f({a:1})", `{"a":1}`, false},
+		{"f(null)", `null`, false},
+		{"f(1)", `1`, false},
+		{"f('x')", `"x"`, false},
+		{"f([1,2,3])", `[1,2,3]`, false},
+		{"f(function(){})", `{}`, false},
+		{"f()", `[1,2,3]`, true},
+	} {
+		t.Run(e.c, func(t *testing.T) {
+			vm := New()
+			vm.Set("f", func(m json.RawMessage) json.RawMessage { return m })
+			r, err := vm.Run(e.c)
+			if err != nil {
+				if !e.e {
+					t.Error("err should be nil")
+					t.Fail()
+				}
+
+				return
+			}
+
+			if e.e {
+				t.Error("err should not be nil")
+				t.Fail()
+				return
+			}
+
+			v, err := r.Export()
+			if err != nil {
+				t.Error(err)
+				t.Fail()
+			}
+
+			m, ok := v.(json.RawMessage)
+			if !ok {
+				t.Error("result should be json.RawMessage")
+				t.Fail()
+			}
+
+			if !bytes.Equal(m, json.RawMessage(e.r)) {
+				t.Errorf("output is wrong\nexpected: %s\nactual:   %s\n", e.r, m)
+				t.Fail()
+			}
+		})
+	}
+}
diff --git a/regexp_test.go b/regexp_test.go
index 8e65ee4..41b60cc 100644
--- a/regexp_test.go
+++ b/regexp_test.go
@@ -36,13 +36,13 @@ func TestRegExp(t *testing.T) {
 		result := test(`/(a)?/.exec('b')`, ",")
 		is(result._object().get("0"), "")
 		is(result._object().get("1"), "undefined")
-		is(result._object().get("length"), 2)
+		is(result._object().get(propertyLength), 2)
 
 		result = test(`/(a)?(b)?/.exec('b')`, "b,,b")
 		is(result._object().get("0"), "b")
 		is(result._object().get("1"), "undefined")
 		is(result._object().get("2"), "b")
-		is(result._object().get("length"), 3)
+		is(result._object().get(propertyLength), 3)
 
 		test(`/\u0041/.source`, "\\u0041")
 		test(`/\a/.source`, "\\a")
@@ -121,6 +121,21 @@ func TestRegExp_exec(t *testing.T) {
             [ ghi, lastIndex ];
         `, "3,7")
 
+		test(`
+            abc = /(\d)?(s)/g;
+            def = 's';
+            ghi = abc.exec(def);
+            [ ghi[1] === undefined, ghi[2] === 's' ];
+        `, "true,true")
+
+		test(`
+            abc = /(\d)?(s)/g;
+            def = '%s';
+            abc.lastIndex = 1;
+            ghi = abc.exec(def);
+            [ ghi[1] === undefined, ghi[2] === 's' ];
+        `, "true,true")
+
 		test(`
             var abc = /[abc](\d)?/.exec("a0 b c1 d3");
             [ abc.length, abc.input, abc.index, abc ];
@@ -256,7 +271,7 @@ func TestRegExp_controlCharacter(t *testing.T) {
 		test, _ := test()
 
 		for code := 0x41; code < 0x5a; code++ {
-			string_ := string(code - 64)
+			string_ := string(rune(code - 64))
 			test(fmt.Sprintf(`
                 var code = 0x%x;
                 var string = String.fromCharCode(code %% 32);
diff --git a/runtime_test.go b/runtime_test.go
index 2310e96..ff71cef 100644
--- a/runtime_test.go
+++ b/runtime_test.go
@@ -857,3 +857,48 @@ func Test_stringArray(t *testing.T) {
 		is(r1, "these are strings")
 	})
 }
+
+type goByteArrayWithMethodsTest [8]byte
+
+func (g goByteArrayWithMethodsTest) S() string    { return string(g[:]) }
+func (g goByteArrayWithMethodsTest) F(i int) byte { return g[i] }
+
+func Test_goByteArrayWithMethods_typeof_S(t *testing.T) {
+	a := goByteArrayWithMethodsTest{97, 98, 99, 100, 101, 102, 103, 104}
+
+	tt(t, func() {
+		test, vm := test()
+		vm.Set("a", a)
+		is(test("typeof a.S").export(), "function")
+	})
+}
+
+func Test_goByteArrayWithMethods_S(t *testing.T) {
+	a := goByteArrayWithMethodsTest{97, 98, 99, 100, 101, 102, 103, 104}
+
+	tt(t, func() {
+		test, vm := test()
+		vm.Set("a", a)
+		is(test("a.S()").export(), "abcdefgh")
+	})
+}
+
+func Test_goByteArrayWithMethods_F0(t *testing.T) {
+	a := goByteArrayWithMethodsTest{97, 98, 99, 100, 101, 102, 103, 104}
+
+	tt(t, func() {
+		test, vm := test()
+		vm.Set("a", a)
+		is(test("a.F(0)").export(), 97)
+	})
+}
+
+func Test_goByteArrayWithMethods_F1(t *testing.T) {
+	a := goByteArrayWithMethodsTest{97, 98, 99, 100, 101, 102, 103, 104}
+
+	tt(t, func() {
+		test, vm := test()
+		vm.Set("a", a)
+		is(test("a.F(1)").export(), 98)
+	})
+}
diff --git a/test/tester.go b/test/tester.go
index ea694fd..05d02c3 100644
--- a/test/tester.go
+++ b/test/tester.go
@@ -42,7 +42,7 @@ var target = map[string]string{
 // http://api.cdnjs.com/libraries
 
 func fetch(name, location string) error {
-	response, err := http.Get(location)
+	response, err := http.Get(location) // nolint: noctx
 	if err != nil {
 		return err
 	}
@@ -110,7 +110,7 @@ func main() {
 	err := func() error {
 
 		if flag.Arg(0) == "fetch" {
-			response, err := http.Get("http://api.cdnjs.com/libraries")
+			response, err := http.Get("http://api.cdnjs.com/libraries") // nolint: noctx
 			if err != nil {
 				return err
 			}
@@ -166,8 +166,8 @@ func main() {
 					case "parse":
 						fmt.Fprintln(writer, name, "\t| pass (parse)")
 					case "re2":
-						continue
 						fmt.Fprintln(writer, name, "\t| unknown (re2)")
+						continue
 					}
 				} else {
 					fmt.Fprintln(writer, name, "\t| fail")
diff --git a/testing_test.go b/testing_test.go
index a210a7d..d4d36d9 100644
--- a/testing_test.go
+++ b/testing_test.go
@@ -10,8 +10,9 @@ import (
 )
 
 func tt(t *testing.T, arguments ...func()) {
+	t.Helper()
 	halt := errors.New("A test was taking too long")
-	timer := time.AfterFunc(2*time.Second, func() {
+	timer := time.AfterFunc(20*time.Second, func() {
 		panic(halt)
 	})
 	defer func() {
diff --git a/type_go_struct_test.go b/type_go_struct_test.go
new file mode 100644
index 0000000..e9e6e00
--- /dev/null
+++ b/type_go_struct_test.go
@@ -0,0 +1,78 @@
+package otto
+
+import (
+	"testing"
+)
+
+func TestGoStructEmbeddedFields(t *testing.T) {
+	type A struct {
+		A1 string `json:"a1"`
+		A2 string `json:"a2"`
+		A3 string `json:"a3"`
+	}
+
+	type B struct {
+		A
+		B1 string `json:"b1"`
+	}
+
+	tt(t, func() {
+		test, vm := test()
+
+		var b B
+
+		b.A1 = "a1"
+		b.A2 = "a2"
+		b.A3 = "a3"
+		b.B1 = "b1"
+
+		vm.Set("v", B{A{"a1", "a2", "a3"}, "b1"})
+
+		test(`[v.a1,v.a2,v.a3,v.b1]`, "a1,a2,a3,b1")
+	})
+}
+
+func TestGoStructNilBoolPointerField(t *testing.T) {
+	type S struct {
+		A int         `json:"a"`
+		B *bool       `json:"b"`
+		C interface{} `json:"c"`
+	}
+
+	tt(t, func() {
+		test, vm := test()
+		vm.Set("s", S{A: 1, B: nil, C: nil})
+		test(`'a' in s`, true)
+		test(`typeof s.a`, "number")
+		test(`'b' in s`, true)
+		test(`typeof s.b`, "undefined")
+		test(`'c' in s`, true)
+		test(`typeof s.c`, "undefined")
+	})
+}
+
+func TestGoStructError(t *testing.T) {
+	type S1 struct {
+		A string `json:"a"`
+		B string `json:"b"`
+	}
+
+	type S2 struct {
+		A []S1 `json:"a"`
+		B S1   `json:"b"`
+	}
+
+	type S3 struct {
+		A []S2 `json:"a"`
+		B S2   `json:"b"`
+	}
+
+	tt(t, func() {
+		test, vm := test()
+		vm.Set("fn", func(s *S3) string { return "cool" })
+		test(
+			`(function() { try { fn({a:[{a:[{c:"x"}]}]}) } catch (ex) { return ex } })()`,
+			`TypeError: can't convert to *otto.S3: couldn't convert property "a" of otto.S3: couldn't convert element 0 of []otto.S2: couldn't convert property "a" of otto.S2: couldn't convert element 0 of []otto.S1: can't convert property "c" of otto.S1: field does not exist`,
+		)
+	})
+}
diff --git a/value_test.go b/value_test.go
index f0c6ef0..88772bc 100644
--- a/value_test.go
+++ b/value_test.go
@@ -253,14 +253,14 @@ func TestExport(t *testing.T) {
 			3.1459,
 			[]interface{}{true, false, 0, 3.1459, "abc"},
 			map[string]interface{}{
-				"Boolean": true,
-				"Number":  3.1459,
-				"String":  "abc",
-				"Array":   []interface{}{false, 0, "", nil},
-				"Object": map[string]interface{}{
-					"Boolean": false,
-					"Number":  0,
-					"String":  "def",
+				classBoolean: true,
+				classNumber:  3.1459,
+				classString:  "abc",
+				classArray:   []interface{}{false, 0, "", nil},
+				classObject: map[string]interface{}{
+					classBoolean: false,
+					classNumber:  0,
+					classString:  "def",
 				},
 			},
 		}