mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 21:26:42 +00:00
Merge branch 'develop' into bzz
This commit is contained in:
commit
d8dfe4112d
972 changed files with 63674 additions and 30058 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -1,3 +1,6 @@
|
|||
[submodule "ethereal/assets/samplecoin"]
|
||||
path = ethereal/assets/samplecoin
|
||||
url = git@github.com:obscuren/SampleCoin.git
|
||||
[submodule "cmd/mist/assets/ext/ethereum.js"]
|
||||
path = cmd/mist/assets/ext/ethereum.js
|
||||
url = https://github.com/ethereum/ethereum.js
|
||||
|
|
|
|||
|
|
@ -27,3 +27,10 @@ env:
|
|||
- LD_LIBRARY_PATH=/opt/qt54/lib
|
||||
- secure: "U2U1AmkU4NJBgKR/uUAebQY87cNL0+1JHjnLOmmXwxYYyj5ralWb1aSuSH3qSXiT93qLBmtaUkuv9fberHVqrbAeVlztVdUsKAq7JMQH+M99iFkC9UiRMqHmtjWJ0ok4COD1sRYixxi21wb/JrMe3M1iL4QJVS61iltjHhVdM64="
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/e09ccdce1048c5e03445
|
||||
on_success: change # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: false # default: false
|
||||
|
|
|
|||
|
|
@ -26,12 +26,11 @@ RUN tar -C /usr/local -xzf go*.tar.gz && go version
|
|||
ADD https://api.github.com/repos/ethereum/go-ethereum/git/refs/heads/develop file_does_not_exist
|
||||
|
||||
## Fetch and install go-ethereum
|
||||
RUN go get github.com/tools/godep
|
||||
RUN go get -d github.com/ethereum/go-ethereum/...
|
||||
RUN mkdir -p $GOPATH/src/github.com/ethereum/
|
||||
RUN git clone https://github.com/ethereum/go-ethereum $GOPATH/src/github.com/ethereum/go-ethereum
|
||||
WORKDIR $GOPATH/src/github.com/ethereum/go-ethereum
|
||||
RUN git checkout develop
|
||||
RUN godep restore
|
||||
RUN go install -v ./cmd/ethereum
|
||||
RUN GOPATH=$GOPATH:$GOPATH/src/github.com/ethereum/go-ethereum/Godeps/_workspace go install -v ./cmd/ethereum
|
||||
|
||||
## Run & expose JSON RPC
|
||||
ENTRYPOINT ["ethereum", "-rpc=true", "-rpcport=8545"]
|
||||
|
|
|
|||
8
Godeps/Godeps.json
generated
8
Godeps/Godeps.json
generated
|
|
@ -22,8 +22,8 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/ethereum/ethash",
|
||||
"Comment": "v17-64-ga323708",
|
||||
"Rev": "a323708b8c4d253b8567bf6c72727d1aec302225"
|
||||
"Comment": "v23.1-26-g934bb4f",
|
||||
"Rev": "934bb4f5060ab69d96fb6eba4b9a57facc4e160b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ethereum/serpent-go",
|
||||
|
|
@ -47,8 +47,8 @@
|
|||
"Rev": "ccfcd0245381f0c94c68f50626665eed3c6b726a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/obscuren/otto",
|
||||
"Rev": "cf13cc4228c5e5ce0fe27a7aea90bc10091c4f19"
|
||||
"ImportPath": "github.com/robertkrimen/otto",
|
||||
"Rev": "dea31a3d392779af358ec41f77a07fcc7e9d04ba"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/obscuren/qml",
|
||||
|
|
|
|||
2
Godeps/_workspace/src/github.com/ethereum/ethash/.gitignore
generated
vendored
2
Godeps/_workspace/src/github.com/ethereum/ethash/.gitignore
generated
vendored
|
|
@ -8,3 +8,5 @@ pyethash.egg-info/
|
|||
*.so
|
||||
*~
|
||||
*.swp
|
||||
MANIFEST
|
||||
dist/
|
||||
|
|
|
|||
10
Godeps/_workspace/src/github.com/ethereum/ethash/CMakeLists.txt
generated
vendored
10
Godeps/_workspace/src/github.com/ethereum/ethash/CMakeLists.txt
generated
vendored
|
|
@ -1,7 +1,7 @@
|
|||
cmake_minimum_required(VERSION 2.8.7)
|
||||
project(ethash)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
|
||||
set(ETHHASH_LIBS ethash)
|
||||
|
||||
if (WIN32 AND WANT_CRYPTOPP)
|
||||
|
|
@ -10,6 +10,12 @@ endif()
|
|||
|
||||
add_subdirectory(src/libethash)
|
||||
# bin2h.cmake doesn't work
|
||||
#add_subdirectory(src/libethash-cl EXCLUDE_FROM_ALL)
|
||||
if (NOT OpenCL_FOUND)
|
||||
find_package(OpenCL)
|
||||
endif()
|
||||
|
||||
if (OpenCL_FOUND)
|
||||
add_subdirectory(src/libethash-cl)
|
||||
endif()
|
||||
add_subdirectory(src/benchmark EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(test/c EXCLUDE_FROM_ALL)
|
||||
|
|
|
|||
17
Godeps/_workspace/src/github.com/ethereum/ethash/MANIFEST.in
generated
vendored
Normal file
17
Godeps/_workspace/src/github.com/ethereum/ethash/MANIFEST.in
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
include setup.py
|
||||
|
||||
# C sources
|
||||
include src/libethash/internal.c
|
||||
include src/libethash/sha3.c
|
||||
include src/libethash/util.c
|
||||
include src/python/core.c
|
||||
|
||||
# Headers
|
||||
include src/libethash/compiler.h
|
||||
include src/libethash/data_sizes.h
|
||||
include src/libethash/endian.h
|
||||
include src/libethash/ethash.h
|
||||
include src/libethash/fnv.h
|
||||
include src/libethash/internal.h
|
||||
include src/libethash/sha3.h
|
||||
include src/libethash/util.h
|
||||
7
Godeps/_workspace/src/github.com/ethereum/ethash/Makefile
generated
vendored
7
Godeps/_workspace/src/github.com/ethereum/ethash/Makefile
generated
vendored
|
|
@ -1,3 +1,6 @@
|
|||
.PHONY: clean
|
||||
.PHONY: clean test
|
||||
test:
|
||||
./test/test.sh
|
||||
|
||||
clean:
|
||||
rm -rf *.so pyethash.egg-info/ build/ test/python/python-virtual-env/ test/c/build/ pyethash/*.{so,pyc}
|
||||
rm -rf *.so pyethash.egg-info/ build/ test/python/python-virtual-env/ test/c/build/ pyethash.so test/python/*.pyc dist/ MANIFEST
|
||||
|
|
|
|||
2
Godeps/_workspace/src/github.com/ethereum/ethash/cryptopp/CMakeLists.txt
generated
vendored
2
Godeps/_workspace/src/github.com/ethereum/ethash/cryptopp/CMakeLists.txt
generated
vendored
|
|
@ -8,6 +8,6 @@ file(GLOB SOURCE "../../cryptopp/*.cpp")
|
|||
|
||||
add_library(${LIBRARY} ${HEADERS} ${SOURCE})
|
||||
|
||||
set(CRYPTOPP_INCLUDE_DIRS "../.." PARENT_SCOPE)
|
||||
set(CRYPTOPP_INCLUDE_DIRS "../.." "../../../" PARENT_SCOPE)
|
||||
set(CRYPTOPP_LIBRARIES ${LIBRARY} PARENT_SCOPE)
|
||||
set(CRYPTOPP_FOUND TRUE PARENT_SCOPE)
|
||||
|
|
|
|||
309
Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go
generated
vendored
309
Godeps/_workspace/src/github.com/ethereum/ethash/ethash.go
generated
vendored
|
|
@ -1,3 +1,13 @@
|
|||
/*
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
#################### ####################
|
||||
#################### EDIT AND YOU SHALL FEEL MY WRATH - jeff ####################
|
||||
#################### ####################
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
*/
|
||||
|
||||
package ethash
|
||||
|
||||
/*
|
||||
|
|
@ -11,8 +21,8 @@ import "C"
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"os"
|
||||
|
|
@ -21,25 +31,26 @@ import (
|
|||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethutil"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/pow"
|
||||
)
|
||||
|
||||
var tt256 = new(big.Int).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(0))
|
||||
var minDifficulty = new(big.Int).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(0))
|
||||
|
||||
var powlogger = logger.NewLogger("POW")
|
||||
|
||||
type DAG struct {
|
||||
SeedBlockNum uint64
|
||||
dag unsafe.Pointer // full GB of memory for dag
|
||||
file bool
|
||||
}
|
||||
|
||||
type ParamsAndCache struct {
|
||||
params *C.ethash_params
|
||||
cache *C.ethash_cache
|
||||
SeedBlockNum uint64
|
||||
Epoch uint64
|
||||
}
|
||||
|
||||
type DAG struct {
|
||||
dag unsafe.Pointer // full GB of memory for dag
|
||||
file bool
|
||||
paramsAndCache *ParamsAndCache
|
||||
}
|
||||
|
||||
type Ethash struct {
|
||||
|
|
@ -48,10 +59,9 @@ type Ethash struct {
|
|||
chainManager pow.ChainManager
|
||||
dag *DAG
|
||||
paramsAndCache *ParamsAndCache
|
||||
nextdag unsafe.Pointer
|
||||
ret *C.ethash_return_value
|
||||
dagMutex *sync.Mutex
|
||||
cacheMutex *sync.Mutex
|
||||
dagMutex *sync.RWMutex
|
||||
cacheMutex *sync.RWMutex
|
||||
}
|
||||
|
||||
func parseNonce(nonce []byte) (uint64, error) {
|
||||
|
|
@ -65,151 +75,214 @@ func parseNonce(nonce []byte) (uint64, error) {
|
|||
|
||||
const epochLength uint64 = 30000
|
||||
|
||||
func GetSeedBlockNum(blockNum uint64) uint64 {
|
||||
var seedBlockNum uint64 = 0
|
||||
if blockNum > epochLength {
|
||||
seedBlockNum = ((blockNum - 1) / epochLength) * epochLength
|
||||
func makeParamsAndCache(chainManager pow.ChainManager, blockNum uint64) (*ParamsAndCache, error) {
|
||||
if blockNum >= epochLength*2048 {
|
||||
return nil, fmt.Errorf("block number is out of bounds (value %v, limit is %v)", blockNum, epochLength*2048)
|
||||
}
|
||||
return seedBlockNum
|
||||
}
|
||||
|
||||
/*
|
||||
XXX THIS DOESN'T WORK!! NEEDS FIXING
|
||||
blockEpoch will underflow and wrap around causing massive issues
|
||||
func GetSeedBlockNum(blockNum uint64) uint64 {
|
||||
var seedBlockNum uint64 = 0
|
||||
if blockNum > epochLength {
|
||||
seedBlockNum = ((blockNum - 1) / epochLength) * epochLength
|
||||
}
|
||||
return seedBlockNum
|
||||
}
|
||||
*/
|
||||
|
||||
func makeParamsAndCache(chainManager pow.ChainManager, blockNum uint64) *ParamsAndCache {
|
||||
seedBlockNum := GetSeedBlockNum(blockNum)
|
||||
paramsAndCache := &ParamsAndCache{
|
||||
params: new(C.ethash_params),
|
||||
cache: new(C.ethash_cache),
|
||||
SeedBlockNum: seedBlockNum,
|
||||
Epoch: blockNum / epochLength,
|
||||
}
|
||||
C.ethash_params_init(paramsAndCache.params, C.uint32_t(seedBlockNum))
|
||||
paramsAndCache.cache.mem = C.malloc(paramsAndCache.params.cache_size)
|
||||
seedHash := chainManager.GetBlockByNumber(seedBlockNum).SeedHash()
|
||||
C.ethash_params_init(paramsAndCache.params, C.uint32_t(uint32(blockNum)))
|
||||
paramsAndCache.cache.mem = C.malloc(C.size_t(paramsAndCache.params.cache_size))
|
||||
|
||||
log.Println("Making Cache")
|
||||
seedHash, err := GetSeedHash(blockNum)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
powlogger.Infoln("Making Cache")
|
||||
start := time.Now()
|
||||
C.ethash_mkcache(paramsAndCache.cache, paramsAndCache.params, (*C.uint8_t)(unsafe.Pointer(&seedHash[0])))
|
||||
log.Println("Took:", time.Since(start))
|
||||
powlogger.Infoln("Took:", time.Since(start))
|
||||
|
||||
return paramsAndCache
|
||||
return paramsAndCache, nil
|
||||
}
|
||||
|
||||
func (pow *Ethash) updateCache() {
|
||||
func (pow *Ethash) UpdateCache(force bool) error {
|
||||
pow.cacheMutex.Lock()
|
||||
seedNum := GetSeedBlockNum(pow.chainManager.CurrentBlock().NumberU64())
|
||||
if pow.paramsAndCache.SeedBlockNum != seedNum {
|
||||
pow.paramsAndCache = makeParamsAndCache(pow.chainManager, pow.chainManager.CurrentBlock().NumberU64())
|
||||
defer pow.cacheMutex.Unlock()
|
||||
|
||||
thisEpoch := pow.chainManager.CurrentBlock().NumberU64() / epochLength
|
||||
if force || pow.paramsAndCache.Epoch != thisEpoch {
|
||||
var err error
|
||||
pow.paramsAndCache, err = makeParamsAndCache(pow.chainManager, pow.chainManager.CurrentBlock().NumberU64())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pow.cacheMutex.Unlock()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeDAG(p *ParamsAndCache) *DAG {
|
||||
d := &DAG{
|
||||
dag: C.malloc(p.params.full_size),
|
||||
SeedBlockNum: p.SeedBlockNum,
|
||||
dag: C.malloc(C.size_t(p.params.full_size)),
|
||||
file: false,
|
||||
paramsAndCache: p,
|
||||
}
|
||||
|
||||
donech := make(chan string)
|
||||
go func() {
|
||||
t := time.NewTicker(5 * time.Second)
|
||||
tstart := time.Now()
|
||||
done:
|
||||
for {
|
||||
select {
|
||||
case <-t.C:
|
||||
powlogger.Infof("... still generating DAG (%v) ...\n", time.Since(tstart).Seconds())
|
||||
case str := <-donech:
|
||||
powlogger.Infof("... %s ...\n", str)
|
||||
break done
|
||||
}
|
||||
}
|
||||
}()
|
||||
C.ethash_compute_full_data(d.dag, p.params, p.cache)
|
||||
donech <- "DAG generation completed"
|
||||
return d
|
||||
}
|
||||
|
||||
func (pow *Ethash) writeDagToDisk(dag *DAG, seedNum uint64) *os.File {
|
||||
data := C.GoBytes(unsafe.Pointer(dag.dag), C.int(pow.paramsAndCache.params.full_size))
|
||||
func (pow *Ethash) writeDagToDisk(dag *DAG, epoch uint64) *os.File {
|
||||
if epoch > 2048 {
|
||||
panic(fmt.Errorf("Epoch must be less than 2048 (is %v)", epoch))
|
||||
}
|
||||
data := C.GoBytes(unsafe.Pointer(dag.dag), C.int(dag.paramsAndCache.params.full_size))
|
||||
file, err := os.Create("/tmp/dag")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
num := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(num, seedNum)
|
||||
dataEpoch := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(dataEpoch, epoch)
|
||||
|
||||
file.Write(num)
|
||||
file.Write(dataEpoch)
|
||||
file.Write(data)
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
func (pow *Ethash) UpdateDAG() {
|
||||
pow.cacheMutex.Lock()
|
||||
pow.dagMutex.Lock()
|
||||
blockNum := pow.chainManager.CurrentBlock().NumberU64()
|
||||
if blockNum >= epochLength*2048 {
|
||||
// This will crash in the 2030s or 2040s
|
||||
panic(fmt.Errorf("Current block number is out of bounds (value %v, limit is %v)", blockNum, epochLength*2048))
|
||||
}
|
||||
|
||||
seedNum := GetSeedBlockNum(pow.chainManager.CurrentBlock().NumberU64())
|
||||
if pow.dag == nil || pow.dag.SeedBlockNum != seedNum {
|
||||
pow.dagMutex.Lock()
|
||||
defer pow.dagMutex.Unlock()
|
||||
thisEpoch := blockNum / epochLength
|
||||
if pow.dag == nil || pow.dag.paramsAndCache.Epoch != thisEpoch {
|
||||
if pow.dag != nil && pow.dag.dag != nil {
|
||||
C.free(pow.dag.dag)
|
||||
pow.dag.dag = nil
|
||||
}
|
||||
|
||||
path := path.Join("/", "tmp", "dag")
|
||||
pow.dag = nil
|
||||
log.Println("Generating dag")
|
||||
start := time.Now()
|
||||
if pow.dag != nil && pow.dag.paramsAndCache.cache.mem != nil {
|
||||
C.free(pow.dag.paramsAndCache.cache.mem)
|
||||
pow.dag.paramsAndCache.cache.mem = nil
|
||||
}
|
||||
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
log.Printf("No dag found in '%s'. Generating new dago(takes a while)...", path)
|
||||
pow.dag = makeDAG(pow.paramsAndCache)
|
||||
file = pow.writeDagToDisk(pow.dag, seedNum)
|
||||
} else {
|
||||
data, err := ioutil.ReadAll(file)
|
||||
// Make the params and cache for the DAG
|
||||
paramsAndCache, err := makeParamsAndCache(pow.chainManager, blockNum)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
num := binary.BigEndian.Uint64(data[0:8])
|
||||
if num < seedNum {
|
||||
log.Printf("Old found. Generating new dag (takes a while)...")
|
||||
pow.dag = makeDAG(pow.paramsAndCache)
|
||||
file = pow.writeDagToDisk(pow.dag, seedNum)
|
||||
// TODO: On non-SSD disks, loading the DAG from disk takes longer than generating it in memory
|
||||
pow.paramsAndCache = paramsAndCache
|
||||
path := path.Join("/", "tmp", "dag")
|
||||
pow.dag = nil
|
||||
powlogger.Infoln("Retrieving DAG")
|
||||
start := time.Now()
|
||||
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
powlogger.Infof("No DAG found. Generating new DAG in '%s' (this takes a while)...\n", path)
|
||||
pow.dag = makeDAG(paramsAndCache)
|
||||
file = pow.writeDagToDisk(pow.dag, thisEpoch)
|
||||
pow.dag.file = true
|
||||
} else {
|
||||
data, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
powlogger.Infof("DAG load err: %v\n", err)
|
||||
}
|
||||
|
||||
if len(data) < 8 {
|
||||
powlogger.Infof("DAG in '%s' is less than 8 bytes, it must be corrupted. Generating new DAG (this takes a while)...\n", path)
|
||||
pow.dag = makeDAG(paramsAndCache)
|
||||
file = pow.writeDagToDisk(pow.dag, thisEpoch)
|
||||
pow.dag.file = true
|
||||
} else {
|
||||
dataEpoch := binary.BigEndian.Uint64(data[0:8])
|
||||
if dataEpoch < thisEpoch {
|
||||
powlogger.Infof("DAG in '%s' is stale. Generating new DAG (this takes a while)...\n", path)
|
||||
pow.dag = makeDAG(paramsAndCache)
|
||||
file = pow.writeDagToDisk(pow.dag, thisEpoch)
|
||||
pow.dag.file = true
|
||||
} else if dataEpoch > thisEpoch {
|
||||
// FIXME
|
||||
panic(fmt.Errorf("Saved DAG in '%s' reports to be from future epoch %v (current epoch is %v)\n", path, dataEpoch, thisEpoch))
|
||||
} else if len(data) != (int(paramsAndCache.params.full_size) + 8) {
|
||||
powlogger.Infof("DAG in '%s' is corrupted. Generating new DAG (this takes a while)...\n", path)
|
||||
pow.dag = makeDAG(paramsAndCache)
|
||||
file = pow.writeDagToDisk(pow.dag, thisEpoch)
|
||||
pow.dag.file = true
|
||||
} else {
|
||||
data = data[8:]
|
||||
pow.dag = &DAG{
|
||||
dag: unsafe.Pointer(&data[0]),
|
||||
file: true,
|
||||
SeedBlockNum: pow.paramsAndCache.SeedBlockNum,
|
||||
paramsAndCache: paramsAndCache,
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Println("Took:", time.Since(start))
|
||||
}
|
||||
powlogger.Infoln("Took:", time.Since(start))
|
||||
|
||||
file.Close()
|
||||
}
|
||||
|
||||
pow.dagMutex.Unlock()
|
||||
pow.cacheMutex.Unlock()
|
||||
}
|
||||
|
||||
func New(chainManager pow.ChainManager) *Ethash {
|
||||
paramsAndCache, err := makeParamsAndCache(chainManager, chainManager.CurrentBlock().NumberU64())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &Ethash{
|
||||
turbo: true,
|
||||
paramsAndCache: makeParamsAndCache(chainManager, chainManager.CurrentBlock().NumberU64()),
|
||||
paramsAndCache: paramsAndCache,
|
||||
chainManager: chainManager,
|
||||
dag: nil,
|
||||
cacheMutex: new(sync.Mutex),
|
||||
dagMutex: new(sync.Mutex),
|
||||
cacheMutex: new(sync.RWMutex),
|
||||
dagMutex: new(sync.RWMutex),
|
||||
}
|
||||
}
|
||||
|
||||
func (pow *Ethash) DAGSize() uint64 {
|
||||
return uint64(pow.paramsAndCache.params.full_size)
|
||||
return uint64(pow.dag.paramsAndCache.params.full_size)
|
||||
}
|
||||
|
||||
func (pow *Ethash) CacheSize() uint64 {
|
||||
return uint64(pow.paramsAndCache.params.cache_size)
|
||||
}
|
||||
|
||||
func (pow *Ethash) GetSeedHash(blockNum uint64) []byte {
|
||||
seednum := GetSeedBlockNum(blockNum)
|
||||
return pow.chainManager.GetBlockByNumber(seednum).SeedHash()
|
||||
func GetSeedHash(blockNum uint64) ([]byte, error) {
|
||||
if blockNum >= epochLength*2048 {
|
||||
return nil, fmt.Errorf("block number is out of bounds (value %v, limit is %v)", blockNum, epochLength*2048)
|
||||
}
|
||||
|
||||
epoch := blockNum / epochLength
|
||||
seedHash := make([]byte, 32)
|
||||
var i uint64
|
||||
for i = 0; i < 32; i++ {
|
||||
seedHash[i] = 0
|
||||
}
|
||||
for i = 0; i < epoch; i++ {
|
||||
seedHash = crypto.Sha3(seedHash)
|
||||
}
|
||||
return seedHash, nil
|
||||
}
|
||||
|
||||
func (pow *Ethash) Stop() {
|
||||
|
|
@ -224,17 +297,18 @@ func (pow *Ethash) Stop() {
|
|||
if pow.dag.dag != nil && !pow.dag.file {
|
||||
C.free(pow.dag.dag)
|
||||
}
|
||||
if pow.dag != nil && pow.dag.paramsAndCache != nil && pow.dag.paramsAndCache.cache.mem != nil {
|
||||
C.free(pow.dag.paramsAndCache.cache.mem)
|
||||
pow.dag.paramsAndCache.cache.mem = nil
|
||||
}
|
||||
pow.dag.dag = nil
|
||||
}
|
||||
|
||||
func (pow *Ethash) Search(block pow.Block, stop <-chan struct{}) (uint64, []byte, []byte) {
|
||||
//pow.UpdateDAG()
|
||||
pow.UpdateDAG()
|
||||
|
||||
// Not very elegant, multiple mining instances are not supported
|
||||
//pow.dagMutex.Lock()
|
||||
//pow.cacheMutex.Lock()
|
||||
//defer pow.cacheMutex.Unlock()
|
||||
//defer pow.dagMutex.Unlock()
|
||||
pow.dagMutex.RLock()
|
||||
defer pow.dagMutex.RUnlock()
|
||||
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
miningHash := block.HashNoNonce()
|
||||
|
|
@ -246,7 +320,7 @@ func (pow *Ethash) Search(block pow.Block, stop <-chan struct{}) (uint64, []byte
|
|||
|
||||
nonce := uint64(r.Int63())
|
||||
cMiningHash := (*C.uint8_t)(unsafe.Pointer(&miningHash[0]))
|
||||
target := new(big.Int).Div(tt256, diff)
|
||||
target := new(big.Int).Div(minDifficulty, diff)
|
||||
|
||||
var ret C.ethash_return_value
|
||||
for {
|
||||
|
|
@ -262,14 +336,17 @@ func (pow *Ethash) Search(block pow.Block, stop <-chan struct{}) (uint64, []byte
|
|||
hashes := ((float64(1e9) / float64(elapsed)) * float64(i-starti)) / 1000
|
||||
pow.HashRate = int64(hashes)
|
||||
|
||||
C.ethash_full(&ret, pow.dag.dag, pow.paramsAndCache.params, cMiningHash, C.uint64_t(nonce))
|
||||
result := ethutil.Bytes2Big(C.GoBytes(unsafe.Pointer(&ret.result[0]), C.int(32)))
|
||||
C.ethash_full(&ret, pow.dag.dag, pow.dag.paramsAndCache.params, cMiningHash, C.uint64_t(nonce))
|
||||
result := common.Bytes2Big(C.GoBytes(unsafe.Pointer(&ret.result[0]), C.int(32)))
|
||||
|
||||
// TODO: disagrees with the spec https://github.com/ethereum/wiki/wiki/Ethash#mining
|
||||
if result.Cmp(target) <= 0 {
|
||||
mixDigest := C.GoBytes(unsafe.Pointer(&ret.mix_hash[0]), C.int(32))
|
||||
|
||||
return nonce, mixDigest, pow.GetSeedHash(block.NumberU64())
|
||||
|
||||
seedHash, err := GetSeedHash(block.NumberU64()) // This seedhash is useless
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nonce, mixDigest, seedHash
|
||||
}
|
||||
|
||||
nonce += 1
|
||||
|
|
@ -283,32 +360,40 @@ func (pow *Ethash) Search(block pow.Block, stop <-chan struct{}) (uint64, []byte
|
|||
}
|
||||
|
||||
func (pow *Ethash) Verify(block pow.Block) bool {
|
||||
// Make sure the SeedHash is set correctly
|
||||
if bytes.Compare(block.SeedHash(), pow.GetSeedHash(block.NumberU64())) != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return pow.verify(block.HashNoNonce(), block.MixDigest(), block.Difficulty(), block.NumberU64(), block.Nonce())
|
||||
return pow.verify(block.HashNoNonce().Bytes(), block.MixDigest().Bytes(), block.Difficulty(), block.NumberU64(), block.Nonce())
|
||||
}
|
||||
|
||||
func (pow *Ethash) verify(hash []byte, mixDigest []byte, difficulty *big.Int, blockNum uint64, nonce uint64) bool {
|
||||
// First check: make sure header, mixDigest, nonce are correct without hitting the DAG
|
||||
// Make sure the block num is valid
|
||||
if blockNum >= epochLength*2048 {
|
||||
powlogger.Infoln(fmt.Sprintf("Block number exceeds limit, invalid (value is %v, limit is %v)",
|
||||
blockNum, epochLength*2048))
|
||||
return false
|
||||
}
|
||||
|
||||
// First check: make sure header, mixDigest, nonce are correct without hitting the cache
|
||||
// This is to prevent DOS attacks
|
||||
chash := (*C.uint8_t)(unsafe.Pointer(&hash[0]))
|
||||
cnonce := C.uint64_t(nonce)
|
||||
target := new(big.Int).Div(tt256, difficulty)
|
||||
target := new(big.Int).Div(minDifficulty, difficulty)
|
||||
|
||||
var pAc *ParamsAndCache
|
||||
// If its an old block (doesn't use the current cache)
|
||||
// get the cache for it but don't update (so we don't need the mutex)
|
||||
// Otherwise, it's the current block or a future.
|
||||
// Otherwise, it's the current block or a future block.
|
||||
// If current, updateCache will do nothing.
|
||||
if GetSeedBlockNum(blockNum) < pow.paramsAndCache.SeedBlockNum {
|
||||
pAc = makeParamsAndCache(pow.chainManager, blockNum)
|
||||
if blockNum/epochLength < pow.paramsAndCache.Epoch {
|
||||
var err error
|
||||
// If we can't make the params for some reason, this block is invalid
|
||||
pAc, err = makeParamsAndCache(pow.chainManager, blockNum)
|
||||
if err != nil {
|
||||
powlogger.Infoln(err)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
pow.updateCache()
|
||||
pow.cacheMutex.Lock()
|
||||
defer pow.cacheMutex.Unlock()
|
||||
pow.UpdateCache(false)
|
||||
pow.cacheMutex.RLock()
|
||||
defer pow.cacheMutex.RUnlock()
|
||||
pAc = pow.paramsAndCache
|
||||
}
|
||||
|
||||
|
|
@ -316,7 +401,7 @@ func (pow *Ethash) verify(hash []byte, mixDigest []byte, difficulty *big.Int, bl
|
|||
|
||||
C.ethash_light(ret, pAc.cache, pAc.params, chash, cnonce)
|
||||
|
||||
result := ethutil.Bytes2Big(C.GoBytes(unsafe.Pointer(&ret.result[0]), C.int(32)))
|
||||
result := common.Bytes2Big(C.GoBytes(unsafe.Pointer(&ret.result[0]), C.int(32)))
|
||||
return result.Cmp(target) <= 0
|
||||
}
|
||||
|
||||
|
|
|
|||
329
Godeps/_workspace/src/github.com/ethereum/ethash/js/cache_sizes.js
generated
vendored
Normal file
329
Godeps/_workspace/src/github.com/ethereum/ethash/js/cache_sizes.js
generated
vendored
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
module.exports = [
|
||||
16776896, 16907456, 17039296, 17170112, 17301056, 17432512, 17563072,
|
||||
17693888, 17824192, 17955904, 18087488, 18218176, 18349504, 18481088,
|
||||
18611392, 18742336, 18874304, 19004224, 19135936, 19267264, 19398208,
|
||||
19529408, 19660096, 19791424, 19922752, 20053952, 20184896, 20315968,
|
||||
20446912, 20576576, 20709184, 20840384, 20971072, 21102272, 21233216,
|
||||
21364544, 21494848, 21626816, 21757376, 21887552, 22019392, 22151104,
|
||||
22281536, 22412224, 22543936, 22675264, 22806464, 22935872, 23068096,
|
||||
23198272, 23330752, 23459008, 23592512, 23723968, 23854912, 23986112,
|
||||
24116672, 24247616, 24378688, 24509504, 24640832, 24772544, 24903488,
|
||||
25034432, 25165376, 25296704, 25427392, 25558592, 25690048, 25820096,
|
||||
25951936, 26081728, 26214208, 26345024, 26476096, 26606656, 26737472,
|
||||
26869184, 26998208, 27131584, 27262528, 27393728, 27523904, 27655744,
|
||||
27786688, 27917888, 28049344, 28179904, 28311488, 28441792, 28573504,
|
||||
28700864, 28835648, 28966208, 29096768, 29228608, 29359808, 29490752,
|
||||
29621824, 29752256, 29882816, 30014912, 30144448, 30273728, 30406976,
|
||||
30538432, 30670784, 30799936, 30932672, 31063744, 31195072, 31325248,
|
||||
31456192, 31588288, 31719232, 31850432, 31981504, 32110784, 32243392,
|
||||
32372672, 32505664, 32636608, 32767808, 32897344, 33029824, 33160768,
|
||||
33289664, 33423296, 33554368, 33683648, 33816512, 33947456, 34076992,
|
||||
34208704, 34340032, 34471744, 34600256, 34734016, 34864576, 34993984,
|
||||
35127104, 35258176, 35386688, 35518528, 35650624, 35782336, 35910976,
|
||||
36044608, 36175808, 36305728, 36436672, 36568384, 36699968, 36830656,
|
||||
36961984, 37093312, 37223488, 37355072, 37486528, 37617472, 37747904,
|
||||
37879232, 38009792, 38141888, 38272448, 38403392, 38535104, 38660672,
|
||||
38795584, 38925632, 39059264, 39190336, 39320768, 39452096, 39581632,
|
||||
39713984, 39844928, 39974848, 40107968, 40238144, 40367168, 40500032,
|
||||
40631744, 40762816, 40894144, 41023552, 41155904, 41286208, 41418304,
|
||||
41547712, 41680448, 41811904, 41942848, 42073792, 42204992, 42334912,
|
||||
42467008, 42597824, 42729152, 42860096, 42991552, 43122368, 43253696,
|
||||
43382848, 43515712, 43646912, 43777088, 43907648, 44039104, 44170432,
|
||||
44302144, 44433344, 44564288, 44694976, 44825152, 44956864, 45088448,
|
||||
45219008, 45350464, 45481024, 45612608, 45744064, 45874496, 46006208,
|
||||
46136768, 46267712, 46399424, 46529344, 46660672, 46791488, 46923328,
|
||||
47053504, 47185856, 47316928, 47447872, 47579072, 47710144, 47839936,
|
||||
47971648, 48103232, 48234176, 48365248, 48496192, 48627136, 48757312,
|
||||
48889664, 49020736, 49149248, 49283008, 49413824, 49545152, 49675712,
|
||||
49807168, 49938368, 50069056, 50200256, 50331584, 50462656, 50593472,
|
||||
50724032, 50853952, 50986048, 51117632, 51248576, 51379904, 51510848,
|
||||
51641792, 51773248, 51903296, 52035136, 52164032, 52297664, 52427968,
|
||||
52557376, 52690112, 52821952, 52952896, 53081536, 53213504, 53344576,
|
||||
53475776, 53608384, 53738816, 53870528, 54000832, 54131776, 54263744,
|
||||
54394688, 54525248, 54655936, 54787904, 54918592, 55049152, 55181248,
|
||||
55312064, 55442752, 55574336, 55705024, 55836224, 55967168, 56097856,
|
||||
56228672, 56358592, 56490176, 56621888, 56753728, 56884928, 57015488,
|
||||
57146816, 57278272, 57409216, 57540416, 57671104, 57802432, 57933632,
|
||||
58064576, 58195264, 58326976, 58457408, 58588864, 58720192, 58849984,
|
||||
58981696, 59113024, 59243456, 59375552, 59506624, 59637568, 59768512,
|
||||
59897792, 60030016, 60161984, 60293056, 60423872, 60554432, 60683968,
|
||||
60817216, 60948032, 61079488, 61209664, 61341376, 61471936, 61602752,
|
||||
61733696, 61865792, 61996736, 62127808, 62259136, 62389568, 62520512,
|
||||
62651584, 62781632, 62910784, 63045056, 63176128, 63307072, 63438656,
|
||||
63569216, 63700928, 63831616, 63960896, 64093888, 64225088, 64355392,
|
||||
64486976, 64617664, 64748608, 64879424, 65009216, 65142464, 65273792,
|
||||
65402816, 65535424, 65666752, 65797696, 65927744, 66060224, 66191296,
|
||||
66321344, 66453056, 66584384, 66715328, 66846656, 66977728, 67108672,
|
||||
67239104, 67370432, 67501888, 67631296, 67763776, 67895104, 68026304,
|
||||
68157248, 68287936, 68419264, 68548288, 68681408, 68811968, 68942912,
|
||||
69074624, 69205568, 69337024, 69467584, 69599168, 69729472, 69861184,
|
||||
69989824, 70122944, 70253888, 70385344, 70515904, 70647232, 70778816,
|
||||
70907968, 71040832, 71171648, 71303104, 71432512, 71564992, 71695168,
|
||||
71826368, 71958464, 72089536, 72219712, 72350144, 72482624, 72613568,
|
||||
72744512, 72875584, 73006144, 73138112, 73268672, 73400128, 73530944,
|
||||
73662272, 73793344, 73924544, 74055104, 74185792, 74316992, 74448832,
|
||||
74579392, 74710976, 74841664, 74972864, 75102784, 75233344, 75364544,
|
||||
75497024, 75627584, 75759296, 75890624, 76021696, 76152256, 76283072,
|
||||
76414144, 76545856, 76676672, 76806976, 76937792, 77070016, 77200832,
|
||||
77331392, 77462464, 77593664, 77725376, 77856448, 77987776, 78118336,
|
||||
78249664, 78380992, 78511424, 78642496, 78773056, 78905152, 79033664,
|
||||
79166656, 79297472, 79429568, 79560512, 79690816, 79822784, 79953472,
|
||||
80084672, 80214208, 80346944, 80477632, 80608576, 80740288, 80870848,
|
||||
81002048, 81133504, 81264448, 81395648, 81525952, 81657536, 81786304,
|
||||
81919808, 82050112, 82181312, 82311616, 82443968, 82573376, 82705984,
|
||||
82835776, 82967744, 83096768, 83230528, 83359552, 83491264, 83622464,
|
||||
83753536, 83886016, 84015296, 84147776, 84277184, 84409792, 84540608,
|
||||
84672064, 84803008, 84934336, 85065152, 85193792, 85326784, 85458496,
|
||||
85589312, 85721024, 85851968, 85982656, 86112448, 86244416, 86370112,
|
||||
86506688, 86637632, 86769344, 86900672, 87031744, 87162304, 87293632,
|
||||
87424576, 87555392, 87687104, 87816896, 87947968, 88079168, 88211264,
|
||||
88341824, 88473152, 88603712, 88735424, 88862912, 88996672, 89128384,
|
||||
89259712, 89390272, 89521984, 89652544, 89783872, 89914816, 90045376,
|
||||
90177088, 90307904, 90438848, 90569152, 90700096, 90832832, 90963776,
|
||||
91093696, 91223744, 91356992, 91486784, 91618496, 91749824, 91880384,
|
||||
92012224, 92143552, 92273344, 92405696, 92536768, 92666432, 92798912,
|
||||
92926016, 93060544, 93192128, 93322816, 93453632, 93583936, 93715136,
|
||||
93845056, 93977792, 94109504, 94240448, 94371776, 94501184, 94632896,
|
||||
94764224, 94895552, 95023424, 95158208, 95287744, 95420224, 95550016,
|
||||
95681216, 95811904, 95943872, 96075328, 96203584, 96337856, 96468544,
|
||||
96599744, 96731072, 96860992, 96992576, 97124288, 97254848, 97385536,
|
||||
97517248, 97647808, 97779392, 97910464, 98041408, 98172608, 98303168,
|
||||
98434496, 98565568, 98696768, 98827328, 98958784, 99089728, 99220928,
|
||||
99352384, 99482816, 99614272, 99745472, 99876416, 100007104,
|
||||
100138048, 100267072, 100401088, 100529984, 100662592, 100791872,
|
||||
100925248, 101056064, 101187392, 101317952, 101449408, 101580608,
|
||||
101711296, 101841728, 101973824, 102104896, 102235712, 102366016,
|
||||
102498112, 102628672, 102760384, 102890432, 103021888, 103153472,
|
||||
103284032, 103415744, 103545152, 103677248, 103808576, 103939648,
|
||||
104070976, 104201792, 104332736, 104462528, 104594752, 104725952,
|
||||
104854592, 104988608, 105118912, 105247808, 105381184, 105511232,
|
||||
105643072, 105774784, 105903296, 106037056, 106167872, 106298944,
|
||||
106429504, 106561472, 106691392, 106822592, 106954304, 107085376,
|
||||
107216576, 107346368, 107478464, 107609792, 107739712, 107872192,
|
||||
108003136, 108131392, 108265408, 108396224, 108527168, 108657344,
|
||||
108789568, 108920384, 109049792, 109182272, 109312576, 109444928,
|
||||
109572928, 109706944, 109837888, 109969088, 110099648, 110230976,
|
||||
110362432, 110492992, 110624704, 110755264, 110886208, 111017408,
|
||||
111148864, 111279296, 111410752, 111541952, 111673024, 111803456,
|
||||
111933632, 112066496, 112196416, 112328512, 112457792, 112590784,
|
||||
112715968, 112852672, 112983616, 113114944, 113244224, 113376448,
|
||||
113505472, 113639104, 113770304, 113901376, 114031552, 114163264,
|
||||
114294592, 114425536, 114556864, 114687424, 114818624, 114948544,
|
||||
115080512, 115212224, 115343296, 115473472, 115605184, 115736128,
|
||||
115867072, 115997248, 116128576, 116260288, 116391488, 116522944,
|
||||
116652992, 116784704, 116915648, 117046208, 117178304, 117308608,
|
||||
117440192, 117569728, 117701824, 117833024, 117964096, 118094656,
|
||||
118225984, 118357312, 118489024, 118617536, 118749632, 118882112,
|
||||
119012416, 119144384, 119275328, 119406016, 119537344, 119668672,
|
||||
119798464, 119928896, 120061376, 120192832, 120321728, 120454336,
|
||||
120584512, 120716608, 120848192, 120979136, 121109056, 121241408,
|
||||
121372352, 121502912, 121634752, 121764416, 121895744, 122027072,
|
||||
122157632, 122289088, 122421184, 122550592, 122682944, 122813888,
|
||||
122945344, 123075776, 123207488, 123338048, 123468736, 123600704,
|
||||
123731264, 123861952, 123993664, 124124608, 124256192, 124386368,
|
||||
124518208, 124649024, 124778048, 124911296, 125041088, 125173696,
|
||||
125303744, 125432896, 125566912, 125696576, 125829056, 125958592,
|
||||
126090304, 126221248, 126352832, 126483776, 126615232, 126746432,
|
||||
126876608, 127008704, 127139392, 127270336, 127401152, 127532224,
|
||||
127663552, 127794752, 127925696, 128055232, 128188096, 128319424,
|
||||
128449856, 128581312, 128712256, 128843584, 128973632, 129103808,
|
||||
129236288, 129365696, 129498944, 129629888, 129760832, 129892288,
|
||||
130023104, 130154048, 130283968, 130416448, 130547008, 130678336,
|
||||
130807616, 130939456, 131071552, 131202112, 131331776, 131464384,
|
||||
131594048, 131727296, 131858368, 131987392, 132120256, 132250816,
|
||||
132382528, 132513728, 132644672, 132774976, 132905792, 133038016,
|
||||
133168832, 133299392, 133429312, 133562048, 133692992, 133823296,
|
||||
133954624, 134086336, 134217152, 134348608, 134479808, 134607296,
|
||||
134741056, 134872384, 135002944, 135134144, 135265472, 135396544,
|
||||
135527872, 135659072, 135787712, 135921472, 136052416, 136182848,
|
||||
136313792, 136444864, 136576448, 136707904, 136837952, 136970048,
|
||||
137099584, 137232064, 137363392, 137494208, 137625536, 137755712,
|
||||
137887424, 138018368, 138149824, 138280256, 138411584, 138539584,
|
||||
138672832, 138804928, 138936128, 139066688, 139196864, 139328704,
|
||||
139460032, 139590208, 139721024, 139852864, 139984576, 140115776,
|
||||
140245696, 140376512, 140508352, 140640064, 140769856, 140902336,
|
||||
141032768, 141162688, 141294016, 141426496, 141556544, 141687488,
|
||||
141819584, 141949888, 142080448, 142212544, 142342336, 142474432,
|
||||
142606144, 142736192, 142868288, 142997824, 143129408, 143258944,
|
||||
143392448, 143523136, 143653696, 143785024, 143916992, 144045632,
|
||||
144177856, 144309184, 144440768, 144570688, 144701888, 144832448,
|
||||
144965056, 145096384, 145227584, 145358656, 145489856, 145620928,
|
||||
145751488, 145883072, 146011456, 146144704, 146275264, 146407232,
|
||||
146538176, 146668736, 146800448, 146931392, 147062336, 147193664,
|
||||
147324224, 147455936, 147586624, 147717056, 147848768, 147979456,
|
||||
148110784, 148242368, 148373312, 148503232, 148635584, 148766144,
|
||||
148897088, 149028416, 149159488, 149290688, 149420224, 149551552,
|
||||
149683136, 149814976, 149943616, 150076352, 150208064, 150338624,
|
||||
150470464, 150600256, 150732224, 150862784, 150993088, 151125952,
|
||||
151254976, 151388096, 151519168, 151649728, 151778752, 151911104,
|
||||
152042944, 152174144, 152304704, 152435648, 152567488, 152698816,
|
||||
152828992, 152960576, 153091648, 153222976, 153353792, 153484096,
|
||||
153616192, 153747008, 153878336, 154008256, 154139968, 154270912,
|
||||
154402624, 154533824, 154663616, 154795712, 154926272, 155057984,
|
||||
155188928, 155319872, 155450816, 155580608, 155712064, 155843392,
|
||||
155971136, 156106688, 156237376, 156367424, 156499264, 156630976,
|
||||
156761536, 156892352, 157024064, 157155008, 157284416, 157415872,
|
||||
157545536, 157677248, 157810496, 157938112, 158071744, 158203328,
|
||||
158334656, 158464832, 158596288, 158727616, 158858048, 158988992,
|
||||
159121216, 159252416, 159381568, 159513152, 159645632, 159776192,
|
||||
159906496, 160038464, 160169536, 160300352, 160430656, 160563008,
|
||||
160693952, 160822208, 160956352, 161086784, 161217344, 161349184,
|
||||
161480512, 161611456, 161742272, 161873216, 162002752, 162135872,
|
||||
162266432, 162397888, 162529216, 162660032, 162790976, 162922048,
|
||||
163052096, 163184576, 163314752, 163446592, 163577408, 163707968,
|
||||
163839296, 163969984, 164100928, 164233024, 164364224, 164494912,
|
||||
164625856, 164756672, 164887616, 165019072, 165150016, 165280064,
|
||||
165412672, 165543104, 165674944, 165805888, 165936832, 166067648,
|
||||
166198336, 166330048, 166461248, 166591552, 166722496, 166854208,
|
||||
166985408, 167116736, 167246656, 167378368, 167508416, 167641024,
|
||||
167771584, 167903168, 168034112, 168164032, 168295744, 168427456,
|
||||
168557632, 168688448, 168819136, 168951616, 169082176, 169213504,
|
||||
169344832, 169475648, 169605952, 169738048, 169866304, 169999552,
|
||||
170131264, 170262464, 170393536, 170524352, 170655424, 170782016,
|
||||
170917696, 171048896, 171179072, 171310784, 171439936, 171573184,
|
||||
171702976, 171835072, 171966272, 172097216, 172228288, 172359232,
|
||||
172489664, 172621376, 172747712, 172883264, 173014208, 173144512,
|
||||
173275072, 173407424, 173539136, 173669696, 173800768, 173931712,
|
||||
174063424, 174193472, 174325696, 174455744, 174586816, 174718912,
|
||||
174849728, 174977728, 175109696, 175242688, 175374272, 175504832,
|
||||
175636288, 175765696, 175898432, 176028992, 176159936, 176291264,
|
||||
176422592, 176552512, 176684864, 176815424, 176946496, 177076544,
|
||||
177209152, 177340096, 177470528, 177600704, 177731648, 177864256,
|
||||
177994816, 178126528, 178257472, 178387648, 178518464, 178650176,
|
||||
178781888, 178912064, 179044288, 179174848, 179305024, 179436736,
|
||||
179568448, 179698496, 179830208, 179960512, 180092608, 180223808,
|
||||
180354752, 180485696, 180617152, 180748096, 180877504, 181009984,
|
||||
181139264, 181272512, 181402688, 181532608, 181663168, 181795136,
|
||||
181926592, 182057536, 182190016, 182320192, 182451904, 182582336,
|
||||
182713792, 182843072, 182976064, 183107264, 183237056, 183368384,
|
||||
183494848, 183631424, 183762752, 183893824, 184024768, 184154816,
|
||||
184286656, 184417984, 184548928, 184680128, 184810816, 184941248,
|
||||
185072704, 185203904, 185335616, 185465408, 185596352, 185727296,
|
||||
185859904, 185989696, 186121664, 186252992, 186383552, 186514112,
|
||||
186645952, 186777152, 186907328, 187037504, 187170112, 187301824,
|
||||
187429184, 187562048, 187693504, 187825472, 187957184, 188087104,
|
||||
188218304, 188349376, 188481344, 188609728, 188743616, 188874304,
|
||||
189005248, 189136448, 189265088, 189396544, 189528128, 189660992,
|
||||
189791936, 189923264, 190054208, 190182848, 190315072, 190447424,
|
||||
190577984, 190709312, 190840768, 190971328, 191102656, 191233472,
|
||||
191364032, 191495872, 191626816, 191758016, 191888192, 192020288,
|
||||
192148928, 192282176, 192413504, 192542528, 192674752, 192805952,
|
||||
192937792, 193068608, 193198912, 193330496, 193462208, 193592384,
|
||||
193723456, 193854272, 193985984, 194116672, 194247232, 194379712,
|
||||
194508352, 194641856, 194772544, 194900672, 195035072, 195166016,
|
||||
195296704, 195428032, 195558592, 195690304, 195818176, 195952576,
|
||||
196083392, 196214336, 196345792, 196476736, 196607552, 196739008,
|
||||
196869952, 197000768, 197130688, 197262784, 197394368, 197523904,
|
||||
197656384, 197787584, 197916608, 198049472, 198180544, 198310208,
|
||||
198442432, 198573632, 198705088, 198834368, 198967232, 199097792,
|
||||
199228352, 199360192, 199491392, 199621696, 199751744, 199883968,
|
||||
200014016, 200146624, 200276672, 200408128, 200540096, 200671168,
|
||||
200801984, 200933312, 201062464, 201194944, 201326144, 201457472,
|
||||
201588544, 201719744, 201850816, 201981632, 202111552, 202244032,
|
||||
202374464, 202505152, 202636352, 202767808, 202898368, 203030336,
|
||||
203159872, 203292608, 203423296, 203553472, 203685824, 203816896,
|
||||
203947712, 204078272, 204208192, 204341056, 204472256, 204603328,
|
||||
204733888, 204864448, 204996544, 205125568, 205258304, 205388864,
|
||||
205517632, 205650112, 205782208, 205913536, 206044736, 206176192,
|
||||
206307008, 206434496, 206569024, 206700224, 206831168, 206961856,
|
||||
207093056, 207223616, 207355328, 207486784, 207616832, 207749056,
|
||||
207879104, 208010048, 208141888, 208273216, 208404032, 208534336,
|
||||
208666048, 208796864, 208927424, 209059264, 209189824, 209321792,
|
||||
209451584, 209582656, 209715136, 209845568, 209976896, 210106432,
|
||||
210239296, 210370112, 210501568, 210630976, 210763712, 210894272,
|
||||
211024832, 211156672, 211287616, 211418176, 211549376, 211679296,
|
||||
211812032, 211942592, 212074432, 212204864, 212334016, 212467648,
|
||||
212597824, 212727616, 212860352, 212991424, 213120832, 213253952,
|
||||
213385024, 213515584, 213645632, 213777728, 213909184, 214040128,
|
||||
214170688, 214302656, 214433728, 214564544, 214695232, 214826048,
|
||||
214956992, 215089088, 215219776, 215350592, 215482304, 215613248,
|
||||
215743552, 215874752, 216005312, 216137024, 216267328, 216399296,
|
||||
216530752, 216661696, 216790592, 216923968, 217054528, 217183168,
|
||||
217316672, 217448128, 217579072, 217709504, 217838912, 217972672,
|
||||
218102848, 218233024, 218364736, 218496832, 218627776, 218759104,
|
||||
218888896, 219021248, 219151936, 219281728, 219413056, 219545024,
|
||||
219675968, 219807296, 219938624, 220069312, 220200128, 220331456,
|
||||
220461632, 220592704, 220725184, 220855744, 220987072, 221117888,
|
||||
221249216, 221378368, 221510336, 221642048, 221772736, 221904832,
|
||||
222031808, 222166976, 222297536, 222428992, 222559936, 222690368,
|
||||
222820672, 222953152, 223083968, 223213376, 223345984, 223476928,
|
||||
223608512, 223738688, 223869376, 224001472, 224132672, 224262848,
|
||||
224394944, 224524864, 224657344, 224788288, 224919488, 225050432,
|
||||
225181504, 225312704, 225443776, 225574592, 225704768, 225834176,
|
||||
225966784, 226097216, 226229824, 226360384, 226491712, 226623424,
|
||||
226754368, 226885312, 227015104, 227147456, 227278528, 227409472,
|
||||
227539904, 227669696, 227802944, 227932352, 228065216, 228196288,
|
||||
228326464, 228457792, 228588736, 228720064, 228850112, 228981056,
|
||||
229113152, 229243328, 229375936, 229505344, 229636928, 229769152,
|
||||
229894976, 230030272, 230162368, 230292416, 230424512, 230553152,
|
||||
230684864, 230816704, 230948416, 231079616, 231210944, 231342016,
|
||||
231472448, 231603776, 231733952, 231866176, 231996736, 232127296,
|
||||
232259392, 232388672, 232521664, 232652608, 232782272, 232914496,
|
||||
233043904, 233175616, 233306816, 233438528, 233569984, 233699776,
|
||||
233830592, 233962688, 234092224, 234221888, 234353984, 234485312,
|
||||
234618304, 234749888, 234880832, 235011776, 235142464, 235274048,
|
||||
235403456, 235535936, 235667392, 235797568, 235928768, 236057152,
|
||||
236190272, 236322752, 236453312, 236583616, 236715712, 236846528,
|
||||
236976448, 237108544, 237239104, 237371072, 237501632, 237630784,
|
||||
237764416, 237895232, 238026688, 238157632, 238286912, 238419392,
|
||||
238548032, 238681024, 238812608, 238941632, 239075008, 239206336,
|
||||
239335232, 239466944, 239599168, 239730496, 239861312, 239992384,
|
||||
240122816, 240254656, 240385856, 240516928, 240647872, 240779072,
|
||||
240909632, 241040704, 241171904, 241302848, 241433408, 241565248,
|
||||
241696192, 241825984, 241958848, 242088256, 242220224, 242352064,
|
||||
242481856, 242611648, 242744896, 242876224, 243005632, 243138496,
|
||||
243268672, 243400384, 243531712, 243662656, 243793856, 243924544,
|
||||
244054592, 244187072, 244316608, 244448704, 244580032, 244710976,
|
||||
244841536, 244972864, 245104448, 245233984, 245365312, 245497792,
|
||||
245628736, 245759936, 245889856, 246021056, 246152512, 246284224,
|
||||
246415168, 246545344, 246675904, 246808384, 246939584, 247070144,
|
||||
247199552, 247331648, 247463872, 247593536, 247726016, 247857088,
|
||||
247987648, 248116928, 248249536, 248380736, 248512064, 248643008,
|
||||
248773312, 248901056, 249036608, 249167552, 249298624, 249429184,
|
||||
249560512, 249692096, 249822784, 249954112, 250085312, 250215488,
|
||||
250345792, 250478528, 250608704, 250739264, 250870976, 251002816,
|
||||
251133632, 251263552, 251395136, 251523904, 251657792, 251789248,
|
||||
251919424, 252051392, 252182464, 252313408, 252444224, 252575552,
|
||||
252706624, 252836032, 252968512, 253099712, 253227584, 253361728,
|
||||
253493056, 253623488, 253754432, 253885504, 254017216, 254148032,
|
||||
254279488, 254410432, 254541376, 254672576, 254803264, 254933824,
|
||||
255065792, 255196736, 255326528, 255458752, 255589952, 255721408,
|
||||
255851072, 255983296, 256114624, 256244416, 256374208, 256507712,
|
||||
256636096, 256768832, 256900544, 257031616, 257162176, 257294272,
|
||||
257424448, 257555776, 257686976, 257818432, 257949632, 258079552,
|
||||
258211136, 258342464, 258473408, 258603712, 258734656, 258867008,
|
||||
258996544, 259127744, 259260224, 259391296, 259522112, 259651904,
|
||||
259784384, 259915328, 260045888, 260175424, 260308544, 260438336,
|
||||
260570944, 260700992, 260832448, 260963776, 261092672, 261226304,
|
||||
261356864, 261487936, 261619648, 261750592, 261879872, 262011968,
|
||||
262143424, 262274752, 262404416, 262537024, 262667968, 262799296,
|
||||
262928704, 263061184, 263191744, 263322944, 263454656, 263585216,
|
||||
263716672, 263847872, 263978944, 264108608, 264241088, 264371648,
|
||||
264501184, 264632768, 264764096, 264895936, 265024576, 265158464,
|
||||
265287488, 265418432, 265550528, 265681216, 265813312, 265943488,
|
||||
266075968, 266206144, 266337728, 266468032, 266600384, 266731072,
|
||||
266862272, 266993344, 267124288, 267255616, 267386432, 267516992,
|
||||
267648704, 267777728, 267910592, 268040512, 268172096, 268302784,
|
||||
268435264, 268566208, 268696256, 268828096, 268959296, 269090368,
|
||||
269221312, 269352256, 269482688, 269614784, 269745856, 269876416,
|
||||
270007616, 270139328, 270270272, 270401216, 270531904, 270663616,
|
||||
270791744, 270924736, 271056832, 271186112, 271317184, 271449536,
|
||||
271580992, 271711936, 271843136, 271973056, 272105408, 272236352,
|
||||
272367296, 272498368, 272629568, 272759488, 272891456, 273022784,
|
||||
273153856, 273284672, 273415616, 273547072, 273677632, 273808448,
|
||||
273937088, 274071488, 274200896, 274332992, 274463296, 274595392,
|
||||
274726208, 274857536, 274988992, 275118656, 275250496, 275382208,
|
||||
275513024, 275643968, 275775296, 275906368, 276037184, 276167872,
|
||||
276297664, 276429376, 276560576, 276692672, 276822976, 276955072,
|
||||
277085632, 277216832, 277347008, 277478848, 277609664, 277740992,
|
||||
277868608, 278002624, 278134336, 278265536, 278395328, 278526784,
|
||||
278657728, 278789824, 278921152, 279052096, 279182912, 279313088,
|
||||
279443776, 279576256, 279706048, 279838528, 279969728, 280099648,
|
||||
280230976, 280361408, 280493632, 280622528, 280755392, 280887104,
|
||||
281018176, 281147968, 281278912, 281411392, 281542592, 281673152,
|
||||
281803712, 281935552, 282066496, 282197312, 282329024, 282458816,
|
||||
282590272, 282720832, 282853184, 282983744, 283115072, 283246144,
|
||||
283377344, 283508416, 283639744, 283770304, 283901504, 284032576,
|
||||
284163136, 284294848, 284426176, 284556992, 284687296, 284819264,
|
||||
284950208, 285081536
|
||||
];
|
||||
412
Godeps/_workspace/src/github.com/ethereum/ethash/js/dag_sizes.js
generated
vendored
Normal file
412
Godeps/_workspace/src/github.com/ethereum/ethash/js/dag_sizes.js
generated
vendored
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
module.exports = [
|
||||
1073739904, 1082130304, 1090514816, 1098906752, 1107293056,
|
||||
1115684224, 1124070016, 1132461952, 1140849536, 1149232768,
|
||||
1157627776, 1166013824, 1174404736, 1182786944, 1191180416,
|
||||
1199568512, 1207958912, 1216345216, 1224732032, 1233124736,
|
||||
1241513344, 1249902464, 1258290304, 1266673792, 1275067264,
|
||||
1283453312, 1291844992, 1300234112, 1308619904, 1317010048,
|
||||
1325397376, 1333787776, 1342176128, 1350561664, 1358954368,
|
||||
1367339392, 1375731584, 1384118144, 1392507008, 1400897408,
|
||||
1409284736, 1417673344, 1426062464, 1434451072, 1442839168,
|
||||
1451229056, 1459615616, 1468006016, 1476394112, 1484782976,
|
||||
1493171584, 1501559168, 1509948032, 1518337664, 1526726528,
|
||||
1535114624, 1543503488, 1551892096, 1560278656, 1568669056,
|
||||
1577056384, 1585446272, 1593831296, 1602219392, 1610610304,
|
||||
1619000192, 1627386752, 1635773824, 1644164224, 1652555648,
|
||||
1660943488, 1669332608, 1677721216, 1686109312, 1694497664,
|
||||
1702886272, 1711274624, 1719661184, 1728047744, 1736434816,
|
||||
1744829056, 1753218944, 1761606272, 1769995904, 1778382464,
|
||||
1786772864, 1795157888, 1803550592, 1811937664, 1820327552,
|
||||
1828711552, 1837102976, 1845488768, 1853879936, 1862269312,
|
||||
1870656896, 1879048064, 1887431552, 1895825024, 1904212096,
|
||||
1912601216, 1920988544, 1929379456, 1937765504, 1946156672,
|
||||
1954543232, 1962932096, 1971321728, 1979707264, 1988093056,
|
||||
1996487552, 2004874624, 2013262208, 2021653888, 2030039936,
|
||||
2038430848, 2046819968, 2055208576, 2063596672, 2071981952,
|
||||
2080373632, 2088762752, 2097149056, 2105539712, 2113928576,
|
||||
2122315136, 2130700672, 2139092608, 2147483264, 2155872128,
|
||||
2164257664, 2172642176, 2181035392, 2189426048, 2197814912,
|
||||
2206203008, 2214587264, 2222979712, 2231367808, 2239758208,
|
||||
2248145024, 2256527744, 2264922752, 2273312128, 2281701248,
|
||||
2290086272, 2298476672, 2306867072, 2315251072, 2323639168,
|
||||
2332032128, 2340420224, 2348808064, 2357196416, 2365580416,
|
||||
2373966976, 2382363008, 2390748544, 2399139968, 2407530368,
|
||||
2415918976, 2424307328, 2432695424, 2441084288, 2449472384,
|
||||
2457861248, 2466247808, 2474637184, 2483026816, 2491414144,
|
||||
2499803776, 2508191872, 2516582272, 2524970368, 2533359232,
|
||||
2541743488, 2550134144, 2558525056, 2566913408, 2575301504,
|
||||
2583686528, 2592073856, 2600467328, 2608856192, 2617240448,
|
||||
2625631616, 2634022016, 2642407552, 2650796416, 2659188352,
|
||||
2667574912, 2675965312, 2684352896, 2692738688, 2701130624,
|
||||
2709518464, 2717907328, 2726293376, 2734685056, 2743073152,
|
||||
2751462016, 2759851648, 2768232832, 2776625536, 2785017728,
|
||||
2793401984, 2801794432, 2810182016, 2818571648, 2826959488,
|
||||
2835349376, 2843734144, 2852121472, 2860514432, 2868900992,
|
||||
2877286784, 2885676928, 2894069632, 2902451584, 2910843008,
|
||||
2919234688, 2927622784, 2936011648, 2944400768, 2952789376,
|
||||
2961177728, 2969565568, 2977951616, 2986338944, 2994731392,
|
||||
3003120256, 3011508352, 3019895936, 3028287104, 3036675968,
|
||||
3045063808, 3053452928, 3061837696, 3070228352, 3078615424,
|
||||
3087003776, 3095394944, 3103782272, 3112173184, 3120562048,
|
||||
3128944768, 3137339264, 3145725056, 3154109312, 3162505088,
|
||||
3170893184, 3179280256, 3187669376, 3196056704, 3204445568,
|
||||
3212836736, 3221224064, 3229612928, 3238002304, 3246391168,
|
||||
3254778496, 3263165824, 3271556224, 3279944576, 3288332416,
|
||||
3296719232, 3305110912, 3313500032, 3321887104, 3330273152,
|
||||
3338658944, 3347053184, 3355440512, 3363827072, 3372220288,
|
||||
3380608384, 3388997504, 3397384576, 3405774208, 3414163072,
|
||||
3422551936, 3430937984, 3439328384, 3447714176, 3456104576,
|
||||
3464493952, 3472883584, 3481268864, 3489655168, 3498048896,
|
||||
3506434432, 3514826368, 3523213952, 3531603584, 3539987072,
|
||||
3548380288, 3556763264, 3565157248, 3573545344, 3581934464,
|
||||
3590324096, 3598712704, 3607098752, 3615488384, 3623877248,
|
||||
3632265856, 3640646528, 3649043584, 3657430144, 3665821568,
|
||||
3674207872, 3682597504, 3690984832, 3699367808, 3707764352,
|
||||
3716152448, 3724541056, 3732925568, 3741318016, 3749706368,
|
||||
3758091136, 3766481536, 3774872704, 3783260032, 3791650432,
|
||||
3800036224, 3808427648, 3816815488, 3825204608, 3833592704,
|
||||
3841981568, 3850370432, 3858755968, 3867147904, 3875536256,
|
||||
3883920512, 3892313728, 3900702592, 3909087872, 3917478784,
|
||||
3925868416, 3934256512, 3942645376, 3951032192, 3959422336,
|
||||
3967809152, 3976200064, 3984588416, 3992974976, 4001363584,
|
||||
4009751168, 4018141312, 4026530432, 4034911616, 4043308928,
|
||||
4051695488, 4060084352, 4068472448, 4076862848, 4085249408,
|
||||
4093640576, 4102028416, 4110413696, 4118805632, 4127194496,
|
||||
4135583104, 4143971968, 4152360832, 4160746112, 4169135744,
|
||||
4177525888, 4185912704, 4194303616, 4202691968, 4211076736,
|
||||
4219463552, 4227855488, 4236246656, 4244633728, 4253022848,
|
||||
4261412224, 4269799808, 4278184832, 4286578048, 4294962304,
|
||||
4303349632, 4311743104, 4320130432, 4328521088, 4336909184,
|
||||
4345295488, 4353687424, 4362073472, 4370458496, 4378852736,
|
||||
4387238528, 4395630208, 4404019072, 4412407424, 4420790656,
|
||||
4429182848, 4437571456, 4445962112, 4454344064, 4462738048,
|
||||
4471119232, 4479516544, 4487904128, 4496289664, 4504682368,
|
||||
4513068416, 4521459584, 4529846144, 4538232704, 4546619776,
|
||||
4555010176, 4563402112, 4571790208, 4580174464, 4588567936,
|
||||
4596957056, 4605344896, 4613734016, 4622119808, 4630511488,
|
||||
4638898816, 4647287936, 4655675264, 4664065664, 4672451968,
|
||||
4680842624, 4689231488, 4697620352, 4706007424, 4714397056,
|
||||
4722786176, 4731173248, 4739562368, 4747951744, 4756340608,
|
||||
4764727936, 4773114496, 4781504384, 4789894784, 4798283648,
|
||||
4806667648, 4815059584, 4823449472, 4831835776, 4840226176,
|
||||
4848612224, 4857003392, 4865391488, 4873780096, 4882169728,
|
||||
4890557312, 4898946944, 4907333248, 4915722368, 4924110976,
|
||||
4932499328, 4940889728, 4949276032, 4957666432, 4966054784,
|
||||
4974438016, 4982831488, 4991221376, 4999607168, 5007998848,
|
||||
5016386432, 5024763776, 5033164672, 5041544576, 5049941888,
|
||||
5058329728, 5066717056, 5075107456, 5083494272, 5091883904,
|
||||
5100273536, 5108662144, 5117048192, 5125436032, 5133827456,
|
||||
5142215296, 5150605184, 5158993024, 5167382144, 5175769472,
|
||||
5184157568, 5192543872, 5200936064, 5209324928, 5217711232,
|
||||
5226102656, 5234490496, 5242877312, 5251263872, 5259654016,
|
||||
5268040832, 5276434304, 5284819328, 5293209728, 5301598592,
|
||||
5309986688, 5318374784, 5326764416, 5335151488, 5343542144,
|
||||
5351929472, 5360319872, 5368706944, 5377096576, 5385484928,
|
||||
5393871232, 5402263424, 5410650496, 5419040384, 5427426944,
|
||||
5435816576, 5444205952, 5452594816, 5460981376, 5469367936,
|
||||
5477760896, 5486148736, 5494536832, 5502925952, 5511315328,
|
||||
5519703424, 5528089984, 5536481152, 5544869504, 5553256064,
|
||||
5561645696, 5570032768, 5578423936, 5586811264, 5595193216,
|
||||
5603585408, 5611972736, 5620366208, 5628750464, 5637143936,
|
||||
5645528192, 5653921408, 5662310272, 5670694784, 5679082624,
|
||||
5687474048, 5695864448, 5704251008, 5712641408, 5721030272,
|
||||
5729416832, 5737806208, 5746194304, 5754583936, 5762969984,
|
||||
5771358592, 5779748224, 5788137856, 5796527488, 5804911232,
|
||||
5813300608, 5821692544, 5830082176, 5838468992, 5846855552,
|
||||
5855247488, 5863636096, 5872024448, 5880411008, 5888799872,
|
||||
5897186432, 5905576832, 5913966976, 5922352768, 5930744704,
|
||||
5939132288, 5947522432, 5955911296, 5964299392, 5972688256,
|
||||
5981074304, 5989465472, 5997851008, 6006241408, 6014627968,
|
||||
6023015552, 6031408256, 6039796096, 6048185216, 6056574848,
|
||||
6064963456, 6073351808, 6081736064, 6090128768, 6098517632,
|
||||
6106906496, 6115289216, 6123680896, 6132070016, 6140459648,
|
||||
6148849024, 6157237376, 6165624704, 6174009728, 6182403712,
|
||||
6190792064, 6199176064, 6207569792, 6215952256, 6224345216,
|
||||
6232732544, 6241124224, 6249510272, 6257899136, 6266287744,
|
||||
6274676864, 6283065728, 6291454336, 6299843456, 6308232064,
|
||||
6316620928, 6325006208, 6333395584, 6341784704, 6350174848,
|
||||
6358562176, 6366951296, 6375337856, 6383729536, 6392119168,
|
||||
6400504192, 6408895616, 6417283456, 6425673344, 6434059136,
|
||||
6442444672, 6450837376, 6459223424, 6467613056, 6476004224,
|
||||
6484393088, 6492781952, 6501170048, 6509555072, 6517947008,
|
||||
6526336384, 6534725504, 6543112832, 6551500672, 6559888768,
|
||||
6568278656, 6576662912, 6585055616, 6593443456, 6601834112,
|
||||
6610219648, 6618610304, 6626999168, 6635385472, 6643777408,
|
||||
6652164224, 6660552832, 6668941952, 6677330048, 6685719424,
|
||||
6694107776, 6702493568, 6710882176, 6719274112, 6727662976,
|
||||
6736052096, 6744437632, 6752825984, 6761213824, 6769604224,
|
||||
6777993856, 6786383488, 6794770816, 6803158144, 6811549312,
|
||||
6819937664, 6828326528, 6836706176, 6845101696, 6853491328,
|
||||
6861880448, 6870269312, 6878655104, 6887046272, 6895433344,
|
||||
6903822208, 6912212864, 6920596864, 6928988288, 6937377152,
|
||||
6945764992, 6954149248, 6962544256, 6970928768, 6979317376,
|
||||
6987709312, 6996093824, 7004487296, 7012875392, 7021258624,
|
||||
7029652352, 7038038912, 7046427776, 7054818944, 7063207808,
|
||||
7071595136, 7079980928, 7088372608, 7096759424, 7105149824,
|
||||
7113536896, 7121928064, 7130315392, 7138699648, 7147092352,
|
||||
7155479168, 7163865728, 7172249984, 7180648064, 7189036672,
|
||||
7197424768, 7205810816, 7214196608, 7222589824, 7230975104,
|
||||
7239367552, 7247755904, 7256145536, 7264533376, 7272921472,
|
||||
7281308032, 7289694848, 7298088832, 7306471808, 7314864512,
|
||||
7323253888, 7331643008, 7340029568, 7348419712, 7356808832,
|
||||
7365196672, 7373585792, 7381973888, 7390362752, 7398750592,
|
||||
7407138944, 7415528576, 7423915648, 7432302208, 7440690304,
|
||||
7449080192, 7457472128, 7465860992, 7474249088, 7482635648,
|
||||
7491023744, 7499412608, 7507803008, 7516192384, 7524579968,
|
||||
7532967296, 7541358464, 7549745792, 7558134656, 7566524032,
|
||||
7574912896, 7583300992, 7591690112, 7600075136, 7608466816,
|
||||
7616854912, 7625244544, 7633629824, 7642020992, 7650410368,
|
||||
7658794112, 7667187328, 7675574912, 7683961984, 7692349568,
|
||||
7700739712, 7709130368, 7717519232, 7725905536, 7734295424,
|
||||
7742683264, 7751069056, 7759457408, 7767849088, 7776238208,
|
||||
7784626816, 7793014912, 7801405312, 7809792128, 7818179968,
|
||||
7826571136, 7834957184, 7843347328, 7851732352, 7860124544,
|
||||
7868512384, 7876902016, 7885287808, 7893679744, 7902067072,
|
||||
7910455936, 7918844288, 7927230848, 7935622784, 7944009344,
|
||||
7952400256, 7960786048, 7969176704, 7977565312, 7985953408,
|
||||
7994339968, 8002730368, 8011119488, 8019508096, 8027896192,
|
||||
8036285056, 8044674688, 8053062272, 8061448832, 8069838464,
|
||||
8078227328, 8086616704, 8095006592, 8103393664, 8111783552,
|
||||
8120171392, 8128560256, 8136949376, 8145336704, 8153726848,
|
||||
8162114944, 8170503296, 8178891904, 8187280768, 8195669632,
|
||||
8204058496, 8212444544, 8220834176, 8229222272, 8237612672,
|
||||
8246000768, 8254389376, 8262775168, 8271167104, 8279553664,
|
||||
8287944064, 8296333184, 8304715136, 8313108352, 8321497984,
|
||||
8329885568, 8338274432, 8346663296, 8355052928, 8363441536,
|
||||
8371828352, 8380217984, 8388606592, 8396996224, 8405384576,
|
||||
8413772672, 8422161536, 8430549376, 8438939008, 8447326592,
|
||||
8455715456, 8464104832, 8472492928, 8480882048, 8489270656,
|
||||
8497659776, 8506045312, 8514434944, 8522823808, 8531208832,
|
||||
8539602304, 8547990656, 8556378752, 8564768384, 8573154176,
|
||||
8581542784, 8589933952, 8598322816, 8606705024, 8615099264,
|
||||
8623487872, 8631876992, 8640264064, 8648653952, 8657040256,
|
||||
8665430656, 8673820544, 8682209152, 8690592128, 8698977152,
|
||||
8707374464, 8715763328, 8724151424, 8732540032, 8740928384,
|
||||
8749315712, 8757704576, 8766089344, 8774480768, 8782871936,
|
||||
8791260032, 8799645824, 8808034432, 8816426368, 8824812928,
|
||||
8833199488, 8841591424, 8849976448, 8858366336, 8866757248,
|
||||
8875147136, 8883532928, 8891923328, 8900306816, 8908700288,
|
||||
8917088384, 8925478784, 8933867392, 8942250368, 8950644608,
|
||||
8959032704, 8967420544, 8975809664, 8984197504, 8992584064,
|
||||
9000976256, 9009362048, 9017752448, 9026141312, 9034530688,
|
||||
9042917504, 9051307904, 9059694208, 9068084864, 9076471424,
|
||||
9084861824, 9093250688, 9101638528, 9110027648, 9118416512,
|
||||
9126803584, 9135188096, 9143581312, 9151969664, 9160356224,
|
||||
9168747136, 9177134464, 9185525632, 9193910144, 9202302848,
|
||||
9210690688, 9219079552, 9227465344, 9235854464, 9244244864,
|
||||
9252633472, 9261021824, 9269411456, 9277799296, 9286188928,
|
||||
9294574208, 9302965888, 9311351936, 9319740032, 9328131968,
|
||||
9336516736, 9344907392, 9353296768, 9361685888, 9370074752,
|
||||
9378463616, 9386849408, 9395239808, 9403629184, 9412016512,
|
||||
9420405376, 9428795008, 9437181568, 9445570688, 9453960832,
|
||||
9462346624, 9470738048, 9479121536, 9487515008, 9495903616,
|
||||
9504289664, 9512678528, 9521067904, 9529456256, 9537843584,
|
||||
9546233728, 9554621312, 9563011456, 9571398784, 9579788672,
|
||||
9588178304, 9596567168, 9604954496, 9613343104, 9621732992,
|
||||
9630121856, 9638508416, 9646898816, 9655283584, 9663675776,
|
||||
9672061312, 9680449664, 9688840064, 9697230464, 9705617536,
|
||||
9714003584, 9722393984, 9730772608, 9739172224, 9747561088,
|
||||
9755945344, 9764338816, 9772726144, 9781116544, 9789503872,
|
||||
9797892992, 9806282624, 9814670464, 9823056512, 9831439232,
|
||||
9839833984, 9848224384, 9856613504, 9865000576, 9873391232,
|
||||
9881772416, 9890162816, 9898556288, 9906940544, 9915333248,
|
||||
9923721088, 9932108672, 9940496512, 9948888448, 9957276544,
|
||||
9965666176, 9974048384, 9982441088, 9990830464, 9999219584,
|
||||
10007602816, 10015996544, 10024385152, 10032774016, 10041163648,
|
||||
10049548928, 10057940096, 10066329472, 10074717824, 10083105152,
|
||||
10091495296, 10099878784, 10108272256, 10116660608, 10125049216,
|
||||
10133437312, 10141825664, 10150213504, 10158601088, 10166991232,
|
||||
10175378816, 10183766144, 10192157312, 10200545408, 10208935552,
|
||||
10217322112, 10225712768, 10234099328, 10242489472, 10250876032,
|
||||
10259264896, 10267656064, 10276042624, 10284429184, 10292820352,
|
||||
10301209472, 10309598848, 10317987712, 10326375296, 10334763392,
|
||||
10343153536, 10351541632, 10359930752, 10368318592, 10376707456,
|
||||
10385096576, 10393484672, 10401867136, 10410262144, 10418647424,
|
||||
10427039104, 10435425664, 10443810176, 10452203648, 10460589952,
|
||||
10468982144, 10477369472, 10485759104, 10494147712, 10502533504,
|
||||
10510923392, 10519313536, 10527702656, 10536091264, 10544478592,
|
||||
10552867712, 10561255808, 10569642368, 10578032768, 10586423168,
|
||||
10594805632, 10603200128, 10611588992, 10619976064, 10628361344,
|
||||
10636754048, 10645143424, 10653531776, 10661920384, 10670307968,
|
||||
10678696832, 10687086464, 10695475072, 10703863168, 10712246144,
|
||||
10720639616, 10729026688, 10737414784, 10745806208, 10754190976,
|
||||
10762581376, 10770971264, 10779356288, 10787747456, 10796135552,
|
||||
10804525184, 10812915584, 10821301888, 10829692288, 10838078336,
|
||||
10846469248, 10854858368, 10863247232, 10871631488, 10880023424,
|
||||
10888412032, 10896799616, 10905188992, 10913574016, 10921964672,
|
||||
10930352768, 10938742912, 10947132544, 10955518592, 10963909504,
|
||||
10972298368, 10980687488, 10989074816, 10997462912, 11005851776,
|
||||
11014241152, 11022627712, 11031017344, 11039403904, 11047793024,
|
||||
11056184704, 11064570752, 11072960896, 11081343872, 11089737856,
|
||||
11098128256, 11106514816, 11114904448, 11123293568, 11131680128,
|
||||
11140065152, 11148458368, 11156845696, 11165236864, 11173624192,
|
||||
11182013824, 11190402688, 11198790784, 11207179136, 11215568768,
|
||||
11223957376, 11232345728, 11240734592, 11249122688, 11257511296,
|
||||
11265899648, 11274285952, 11282675584, 11291065472, 11299452544,
|
||||
11307842432, 11316231296, 11324616832, 11333009024, 11341395584,
|
||||
11349782656, 11358172288, 11366560384, 11374950016, 11383339648,
|
||||
11391721856, 11400117376, 11408504192, 11416893568, 11425283456,
|
||||
11433671552, 11442061184, 11450444672, 11458837888, 11467226752,
|
||||
11475611776, 11484003968, 11492392064, 11500780672, 11509169024,
|
||||
11517550976, 11525944448, 11534335616, 11542724224, 11551111808,
|
||||
11559500672, 11567890304, 11576277376, 11584667008, 11593056128,
|
||||
11601443456, 11609830016, 11618221952, 11626607488, 11634995072,
|
||||
11643387776, 11651775104, 11660161664, 11668552576, 11676940928,
|
||||
11685330304, 11693718656, 11702106496, 11710496128, 11718882688,
|
||||
11727273088, 11735660416, 11744050048, 11752437376, 11760824704,
|
||||
11769216128, 11777604736, 11785991296, 11794381952, 11802770048,
|
||||
11811157888, 11819548544, 11827932544, 11836324736, 11844713344,
|
||||
11853100928, 11861486464, 11869879936, 11878268032, 11886656896,
|
||||
11895044992, 11903433088, 11911822976, 11920210816, 11928600448,
|
||||
11936987264, 11945375872, 11953761152, 11962151296, 11970543488,
|
||||
11978928512, 11987320448, 11995708288, 12004095104, 12012486272,
|
||||
12020875136, 12029255552, 12037652096, 12046039168, 12054429568,
|
||||
12062813824, 12071206528, 12079594624, 12087983744, 12096371072,
|
||||
12104759936, 12113147264, 12121534592, 12129924992, 12138314624,
|
||||
12146703232, 12155091584, 12163481216, 12171864704, 12180255872,
|
||||
12188643968, 12197034112, 12205424512, 12213811328, 12222199424,
|
||||
12230590336, 12238977664, 12247365248, 12255755392, 12264143488,
|
||||
12272531584, 12280920448, 12289309568, 12297694592, 12306086528,
|
||||
12314475392, 12322865024, 12331253632, 12339640448, 12348029312,
|
||||
12356418944, 12364805248, 12373196672, 12381580928, 12389969024,
|
||||
12398357632, 12406750592, 12415138432, 12423527552, 12431916416,
|
||||
12440304512, 12448692352, 12457081216, 12465467776, 12473859968,
|
||||
12482245504, 12490636672, 12499025536, 12507411584, 12515801728,
|
||||
12524190592, 12532577152, 12540966272, 12549354368, 12557743232,
|
||||
12566129536, 12574523264, 12582911872, 12591299456, 12599688064,
|
||||
12608074624, 12616463488, 12624845696, 12633239936, 12641631616,
|
||||
12650019968, 12658407296, 12666795136, 12675183232, 12683574656,
|
||||
12691960192, 12700350592, 12708740224, 12717128576, 12725515904,
|
||||
12733906816, 12742295168, 12750680192, 12759071872, 12767460736,
|
||||
12775848832, 12784236928, 12792626816, 12801014656, 12809404288,
|
||||
12817789312, 12826181504, 12834568832, 12842954624, 12851345792,
|
||||
12859732352, 12868122496, 12876512128, 12884901248, 12893289088,
|
||||
12901672832, 12910067584, 12918455168, 12926842496, 12935232896,
|
||||
12943620736, 12952009856, 12960396928, 12968786816, 12977176192,
|
||||
12985563776, 12993951104, 13002341504, 13010730368, 13019115392,
|
||||
13027506304, 13035895168, 13044272512, 13052673152, 13061062528,
|
||||
13069446272, 13077838976, 13086227072, 13094613632, 13103000192,
|
||||
13111393664, 13119782528, 13128157568, 13136559232, 13144945024,
|
||||
13153329536, 13161724288, 13170111872, 13178502784, 13186884736,
|
||||
13195279744, 13203667072, 13212057472, 13220445824, 13228832128,
|
||||
13237221248, 13245610624, 13254000512, 13262388352, 13270777472,
|
||||
13279166336, 13287553408, 13295943296, 13304331904, 13312719488,
|
||||
13321108096, 13329494656, 13337885824, 13346274944, 13354663808,
|
||||
13363051136, 13371439232, 13379825024, 13388210816, 13396605056,
|
||||
13404995456, 13413380224, 13421771392, 13430159744, 13438546048,
|
||||
13446937216, 13455326848, 13463708288, 13472103808, 13480492672,
|
||||
13488875648, 13497269888, 13505657728, 13514045312, 13522435712,
|
||||
13530824576, 13539210112, 13547599232, 13555989376, 13564379008,
|
||||
13572766336, 13581154432, 13589544832, 13597932928, 13606320512,
|
||||
13614710656, 13623097472, 13631477632, 13639874944, 13648264064,
|
||||
13656652928, 13665041792, 13673430656, 13681818496, 13690207616,
|
||||
13698595712, 13706982272, 13715373184, 13723762048, 13732150144,
|
||||
13740536704, 13748926592, 13757316224, 13765700992, 13774090112,
|
||||
13782477952, 13790869376, 13799259008, 13807647872, 13816036736,
|
||||
13824425344, 13832814208, 13841202304, 13849591424, 13857978752,
|
||||
13866368896, 13874754688, 13883145344, 13891533184, 13899919232,
|
||||
13908311168, 13916692096, 13925085056, 13933473152, 13941866368,
|
||||
13950253696, 13958643584, 13967032192, 13975417216, 13983807616,
|
||||
13992197504, 14000582272, 14008973696, 14017363072, 14025752192,
|
||||
14034137984, 14042528384, 14050918016, 14059301504, 14067691648,
|
||||
14076083584, 14084470144, 14092852352, 14101249664, 14109635968,
|
||||
14118024832, 14126407552, 14134804352, 14143188608, 14151577984,
|
||||
14159968384, 14168357248, 14176741504, 14185127296, 14193521024,
|
||||
14201911424, 14210301824, 14218685056, 14227067264, 14235467392,
|
||||
14243855488, 14252243072, 14260630144, 14269021568, 14277409408,
|
||||
14285799296, 14294187904, 14302571392, 14310961792, 14319353728,
|
||||
14327738752, 14336130944, 14344518784, 14352906368, 14361296512,
|
||||
14369685376, 14378071424, 14386462592, 14394848128, 14403230848,
|
||||
14411627392, 14420013952, 14428402304, 14436793472, 14445181568,
|
||||
14453569664, 14461959808, 14470347904, 14478737024, 14487122816,
|
||||
14495511424, 14503901824, 14512291712, 14520677504, 14529064832,
|
||||
14537456768, 14545845632, 14554234496, 14562618496, 14571011456,
|
||||
14579398784, 14587789184, 14596172672, 14604564608, 14612953984,
|
||||
14621341312, 14629724288, 14638120832, 14646503296, 14654897536,
|
||||
14663284864, 14671675264, 14680061056, 14688447616, 14696835968,
|
||||
14705228416, 14713616768, 14722003328, 14730392192, 14738784128,
|
||||
14747172736, 14755561088, 14763947648, 14772336512, 14780725376,
|
||||
14789110144, 14797499776, 14805892736, 14814276992, 14822670208,
|
||||
14831056256, 14839444352, 14847836032, 14856222848, 14864612992,
|
||||
14872997504, 14881388672, 14889775744, 14898165376, 14906553472,
|
||||
14914944896, 14923329664, 14931721856, 14940109696, 14948497024,
|
||||
14956887424, 14965276544, 14973663616, 14982053248, 14990439808,
|
||||
14998830976, 15007216768, 15015605888, 15023995264, 15032385152,
|
||||
15040768384, 15049154944, 15057549184, 15065939072, 15074328448,
|
||||
15082715008, 15091104128, 15099493504, 15107879296, 15116269184,
|
||||
15124659584, 15133042304, 15141431936, 15149824384, 15158214272,
|
||||
15166602368, 15174991232, 15183378304, 15191760512, 15200154496,
|
||||
15208542592, 15216931712, 15225323392, 15233708416, 15242098048,
|
||||
15250489216, 15258875264, 15267265408, 15275654528, 15284043136,
|
||||
15292431488, 15300819584, 15309208192, 15317596544, 15325986176,
|
||||
15334374784, 15342763648, 15351151744, 15359540608, 15367929728,
|
||||
15376318336, 15384706432, 15393092992, 15401481856, 15409869952,
|
||||
15418258816, 15426649984, 15435037568, 15443425664, 15451815296,
|
||||
15460203392, 15468589184, 15476979328, 15485369216, 15493755776,
|
||||
15502146944, 15510534272, 15518924416, 15527311232, 15535699072,
|
||||
15544089472, 15552478336, 15560866688, 15569254528, 15577642624,
|
||||
15586031488, 15594419072, 15602809472, 15611199104, 15619586432,
|
||||
15627975296, 15636364928, 15644753792, 15653141888, 15661529216,
|
||||
15669918848, 15678305152, 15686696576, 15695083136, 15703474048,
|
||||
15711861632, 15720251264, 15728636288, 15737027456, 15745417088,
|
||||
15753804928, 15762194048, 15770582656, 15778971008, 15787358336,
|
||||
15795747712, 15804132224, 15812523392, 15820909696, 15829300096,
|
||||
15837691264, 15846071936, 15854466944, 15862855808, 15871244672,
|
||||
15879634816, 15888020608, 15896409728, 15904799104, 15913185152,
|
||||
15921577088, 15929966464, 15938354816, 15946743424, 15955129472,
|
||||
15963519872, 15971907968, 15980296064, 15988684928, 15997073024,
|
||||
16005460864, 16013851264, 16022241152, 16030629248, 16039012736,
|
||||
16047406976, 16055794816, 16064181376, 16072571264, 16080957824,
|
||||
16089346688, 16097737856, 16106125184, 16114514816, 16122904192,
|
||||
16131292544, 16139678848, 16148066944, 16156453504, 16164839552,
|
||||
16173236096, 16181623424, 16190012032, 16198401152, 16206790528,
|
||||
16215177344, 16223567744, 16231956352, 16240344704, 16248731008,
|
||||
16257117824, 16265504384, 16273898624, 16282281856, 16290668672,
|
||||
16299064192, 16307449216, 16315842176, 16324230016, 16332613504,
|
||||
16341006464, 16349394304, 16357783168, 16366172288, 16374561664,
|
||||
16382951296, 16391337856, 16399726208, 16408116352, 16416505472,
|
||||
16424892032, 16433282176, 16441668224, 16450058624, 16458448768,
|
||||
16466836864, 16475224448, 16483613056, 16492001408, 16500391808,
|
||||
16508779648, 16517166976, 16525555328, 16533944192, 16542330752,
|
||||
16550719616, 16559110528, 16567497088, 16575888512, 16584274816,
|
||||
16592665472, 16601051008, 16609442944, 16617832064, 16626218624,
|
||||
16634607488, 16642996096, 16651385728, 16659773824, 16668163712,
|
||||
16676552576, 16684938112, 16693328768, 16701718144, 16710095488,
|
||||
16718492288, 16726883968, 16735272832, 16743661184, 16752049792,
|
||||
16760436608, 16768827008, 16777214336, 16785599104, 16793992832,
|
||||
16802381696, 16810768768, 16819151744, 16827542656, 16835934848,
|
||||
16844323712, 16852711552, 16861101952, 16869489536, 16877876864,
|
||||
16886265728, 16894653056, 16903044736, 16911431296, 16919821696,
|
||||
16928207488, 16936592768, 16944987776, 16953375616, 16961763968,
|
||||
16970152832, 16978540928, 16986929536, 16995319168, 17003704448,
|
||||
17012096896, 17020481152, 17028870784, 17037262208, 17045649536,
|
||||
17054039936, 17062426496, 17070814336, 17079205504, 17087592064,
|
||||
17095978112, 17104369024, 17112759424, 17121147776, 17129536384,
|
||||
17137926016, 17146314368, 17154700928, 17163089792, 17171480192,
|
||||
17179864192, 17188256896, 17196644992, 17205033856, 17213423488,
|
||||
17221811072, 17230198912, 17238588032, 17246976896, 17255360384,
|
||||
17263754624, 17272143232, 17280530048, 17288918912, 17297309312,
|
||||
17305696384, 17314085504, 17322475136, 17330863744, 17339252096,
|
||||
17347640192, 17356026496, 17364413824, 17372796544, 17381190016,
|
||||
17389583488, 17397972608, 17406360704, 17414748544, 17423135872,
|
||||
17431527296, 17439915904, 17448303232, 17456691584, 17465081728,
|
||||
17473468288, 17481857408, 17490247552, 17498635904, 17507022464,
|
||||
17515409024, 17523801728, 17532189824, 17540577664, 17548966016,
|
||||
17557353344, 17565741184, 17574131584, 17582519168, 17590907008,
|
||||
17599296128, 17607687808, 17616076672, 17624455808, 17632852352,
|
||||
17641238656, 17649630848, 17658018944, 17666403968, 17674794112,
|
||||
17683178368, 17691573376, 17699962496, 17708350592, 17716739968,
|
||||
17725126528, 17733517184, 17741898112, 17750293888, 17758673024,
|
||||
17767070336, 17775458432, 17783848832, 17792236928, 17800625536,
|
||||
17809012352, 17817402752, 17825785984, 17834178944, 17842563968,
|
||||
17850955648, 17859344512, 17867732864, 17876119424, 17884511872,
|
||||
17892900224, 17901287296, 17909677696, 17918058112, 17926451072,
|
||||
17934843776, 17943230848, 17951609216, 17960008576, 17968397696,
|
||||
17976784256, 17985175424, 17993564032, 18001952128, 18010339712,
|
||||
18018728576, 18027116672, 18035503232, 18043894144, 18052283264,
|
||||
18060672128, 18069056384, 18077449856, 18085837184, 18094225792,
|
||||
18102613376, 18111004544, 18119388544, 18127781248, 18136170368,
|
||||
18144558976, 18152947328, 18161336192, 18169724288, 18178108544,
|
||||
18186498944, 18194886784, 18203275648, 18211666048, 18220048768,
|
||||
18228444544, 18236833408, 18245220736
|
||||
];
|
||||
142
Godeps/_workspace/src/github.com/ethereum/ethash/js/ethash.js
generated
vendored
142
Godeps/_workspace/src/github.com/ethereum/ethash/js/ethash.js
generated
vendored
|
|
@ -7,84 +7,73 @@
|
|||
|
||||
var Keccak = require('./keccak');
|
||||
var util = require('./util');
|
||||
var ethUtil = require('ethereumjs-util');
|
||||
|
||||
// 32-bit unsigned modulo
|
||||
function mod32(x, n)
|
||||
{
|
||||
return (x>>>0) % (n>>>0);
|
||||
function mod32(x, n) {
|
||||
return (x >>> 0) % (n >>> 0);
|
||||
}
|
||||
|
||||
function fnv(x, y)
|
||||
{
|
||||
function fnv(x, y) {
|
||||
// js integer multiply by 0x01000193 will lose precision
|
||||
return ((x*0x01000000 | 0) + (x*0x193 | 0)) ^ y;
|
||||
return ((x * 0x01000000 | 0) + (x * 0x193 | 0)) ^ y;
|
||||
}
|
||||
|
||||
function computeCache(params, seedWords)
|
||||
{
|
||||
function computeCache(params, seedWords) {
|
||||
var cache = new Uint32Array(params.cacheSize >> 2);
|
||||
var cacheNodeCount = params.cacheSize >> 6;
|
||||
|
||||
// Initialize cache
|
||||
var keccak = new Keccak();
|
||||
keccak.digestWords(cache, 0, 16, seedWords, 0, seedWords.length);
|
||||
for (var n = 1; n < cacheNodeCount; ++n)
|
||||
{
|
||||
keccak.digestWords(cache, n<<4, 16, cache, (n-1)<<4, 16);
|
||||
for (var n = 1; n < cacheNodeCount; ++n) {
|
||||
keccak.digestWords(cache, n << 4, 16, cache, (n - 1) << 4, 16);
|
||||
}
|
||||
|
||||
var tmp = new Uint32Array(16);
|
||||
|
||||
// Do randmemohash passes
|
||||
for (var r = 0; r < params.cacheRounds; ++r)
|
||||
{
|
||||
for (var n = 0; n < cacheNodeCount; ++n)
|
||||
{
|
||||
for (var r = 0; r < params.cacheRounds; ++r) {
|
||||
for (var n = 0; n < cacheNodeCount; ++n) {
|
||||
var p0 = mod32(n + cacheNodeCount - 1, cacheNodeCount) << 4;
|
||||
var p1 = mod32(cache[n<<4|0], cacheNodeCount) << 4;
|
||||
var p1 = mod32(cache[n << 4 | 0], cacheNodeCount) << 4;
|
||||
|
||||
for (var w = 0; w < 16; w=(w+1)|0)
|
||||
{
|
||||
for (var w = 0; w < 16; w = (w + 1) | 0) {
|
||||
tmp[w] = cache[p0 | w] ^ cache[p1 | w];
|
||||
}
|
||||
|
||||
keccak.digestWords(cache, n<<4, 16, tmp, 0, tmp.length);
|
||||
keccak.digestWords(cache, n << 4, 16, tmp, 0, tmp.length);
|
||||
}
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
function computeDagNode(o_node, params, cache, keccak, nodeIndex)
|
||||
{
|
||||
function computeDagNode(o_node, params, cache, keccak, nodeIndex) {
|
||||
var cacheNodeCount = params.cacheSize >> 6;
|
||||
var dagParents = params.dagParents;
|
||||
|
||||
var c = (nodeIndex % cacheNodeCount) << 4;
|
||||
var mix = o_node;
|
||||
for (var w = 0; w < 16; ++w)
|
||||
{
|
||||
mix[w] = cache[c|w];
|
||||
for (var w = 0; w < 16; ++w) {
|
||||
mix[w] = cache[c | w];
|
||||
}
|
||||
mix[0] ^= nodeIndex;
|
||||
keccak.digestWords(mix, 0, 16, mix, 0, 16);
|
||||
|
||||
for (var p = 0; p < dagParents; ++p)
|
||||
{
|
||||
for (var p = 0; p < dagParents; ++p) {
|
||||
// compute cache node (word) index
|
||||
c = mod32(fnv(nodeIndex ^ p, mix[p&15]), cacheNodeCount) << 4;
|
||||
c = mod32(fnv(nodeIndex ^ p, mix[p & 15]), cacheNodeCount) << 4;
|
||||
|
||||
for (var w = 0; w < 16; ++w)
|
||||
{
|
||||
mix[w] = fnv(mix[w], cache[c|w]);
|
||||
for (var w = 0; w < 16; ++w) {
|
||||
mix[w] = fnv(mix[w], cache[c | w]);
|
||||
}
|
||||
}
|
||||
|
||||
keccak.digestWords(mix, 0, 16, mix, 0, 16);
|
||||
}
|
||||
|
||||
function computeHashInner(mix, params, cache, keccak, tempNode)
|
||||
{
|
||||
var mixParents = params.mixParents|0;
|
||||
function computeHashInner(mix, params, cache, keccak, tempNode) {
|
||||
var mixParents = params.mixParents | 0;
|
||||
var mixWordCount = params.mixSize >> 2;
|
||||
var mixNodeCount = mixWordCount >> 4;
|
||||
var dagPageCount = (params.dagSize / params.mixSize) >> 0;
|
||||
|
|
@ -93,30 +82,25 @@ function computeHashInner(mix, params, cache, keccak, tempNode)
|
|||
var s0 = mix[0];
|
||||
|
||||
// initialise mix from initial 64 bytes
|
||||
for (var w = 16; w < mixWordCount; ++w)
|
||||
{
|
||||
for (var w = 16; w < mixWordCount; ++w) {
|
||||
mix[w] = mix[w & 15];
|
||||
}
|
||||
|
||||
for (var a = 0; a < mixParents; ++a)
|
||||
{
|
||||
var p = mod32(fnv(s0 ^ a, mix[a & (mixWordCount-1)]), dagPageCount);
|
||||
var d = (p * mixNodeCount)|0;
|
||||
for (var a = 0; a < mixParents; ++a) {
|
||||
var p = mod32(fnv(s0 ^ a, mix[a & (mixWordCount - 1)]), dagPageCount);
|
||||
var d = (p * mixNodeCount) | 0;
|
||||
|
||||
for (var n = 0, w = 0; n < mixNodeCount; ++n, w += 16)
|
||||
{
|
||||
computeDagNode(tempNode, params, cache, keccak, (d + n)|0);
|
||||
for (var n = 0, w = 0; n < mixNodeCount; ++n, w += 16) {
|
||||
computeDagNode(tempNode, params, cache, keccak, (d + n) | 0);
|
||||
|
||||
for (var v = 0; v < 16; ++v)
|
||||
{
|
||||
mix[w|v] = fnv(mix[w|v], tempNode[v]);
|
||||
for (var v = 0; v < 16; ++v) {
|
||||
mix[w | v] = fnv(mix[w | v], tempNode[v]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function convertSeed(seed)
|
||||
{
|
||||
function convertSeed(seed) {
|
||||
// todo, reconcile with spec, byte ordering?
|
||||
// todo, big-endian conversion
|
||||
var newSeed = util.toWords(seed);
|
||||
|
|
@ -125,22 +109,54 @@ function convertSeed(seed)
|
|||
return newSeed;
|
||||
}
|
||||
|
||||
exports.defaultParams = function()
|
||||
{
|
||||
var params = exports.params = {
|
||||
REVISION: 23,
|
||||
DATASET_BYTES_INIT: 1073741824,
|
||||
DATASET_BYTES_GROWTH: 8388608,
|
||||
CACHE_BYTES_INIT: 1073741824,
|
||||
CACHE_BYTES_GROWTH: 131072,
|
||||
EPOCH_LENGTH: 30000,
|
||||
MIX_BYTES: 128,
|
||||
HASH_BYTES: 64,
|
||||
DATASET_PARENTS: 256,
|
||||
CACHE_ROUNDS: 3,
|
||||
ACCESSES: 64
|
||||
};
|
||||
|
||||
var cache_sizes = require('./cache_sizes');
|
||||
var dag_sizes = require('./dag_sizes');
|
||||
|
||||
exports.calcSeed = function(blockNum) {
|
||||
var epoch;
|
||||
|
||||
var seed = new Uint8Array(32);
|
||||
|
||||
if (blockNum > cache_sizes.length * params.EPOCH_LENGTH) {
|
||||
return new Error('Time to upgrade to POS!!!');
|
||||
} else {
|
||||
epoch = Math.floor(blockNum / params.EPOCH_LENGTH);
|
||||
|
||||
for (var i = 0; i < epoch; i++) {
|
||||
seed = ethUtil.sha3(new Buffer(seed));
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
exports.defaultParams = function() {
|
||||
return {
|
||||
cacheSize: 1048384,
|
||||
cacheRounds: 3,
|
||||
dagSize: 1073739904,
|
||||
dagParents: 256,
|
||||
mixSize: 128,
|
||||
mixParents: 64,
|
||||
mixParents: 64
|
||||
};
|
||||
};
|
||||
|
||||
exports.Ethash = function(params, seed)
|
||||
{
|
||||
exports.Ethash = function(params, seed) {
|
||||
// precompute cache and related values
|
||||
seed = convertSeed(seed);
|
||||
// seed = convertSeed(seed);
|
||||
var cache = computeCache(params, seed);
|
||||
|
||||
// preallocate buffers/etc
|
||||
|
|
@ -154,24 +170,21 @@ exports.Ethash = function(params, seed)
|
|||
var retWords = new Uint32Array(8);
|
||||
var retBytes = new Uint8Array(retWords.buffer); // supposedly read-only
|
||||
|
||||
this.hash = function(header, nonce)
|
||||
{
|
||||
this.hash = function(header, nonce) {
|
||||
// compute initial hash
|
||||
initBytes.set(header, 0);
|
||||
initBytes.set(nonce, 32);
|
||||
keccak.digestWords(initWords, 0, 16, initWords, 0, 8 + nonce.length/4);
|
||||
keccak.digestWords(initWords, 0, 16, initWords, 0, 8 + nonce.length / 4);
|
||||
|
||||
// compute mix
|
||||
for (var i = 0; i != 16; ++i)
|
||||
{
|
||||
for (var i = 0; i !== 16; ++i) {
|
||||
mixWords[i] = initWords[i];
|
||||
}
|
||||
computeHashInner(mixWords, params, cache, keccak, tempNode);
|
||||
|
||||
// compress mix and append to initWords
|
||||
for (var i = 0; i != mixWords.length; i += 4)
|
||||
{
|
||||
initWords[16 + i/4] = fnv(fnv(fnv(mixWords[i], mixWords[i+1]), mixWords[i+2]), mixWords[i+3]);
|
||||
for (var i = 0; i !== mixWords.length; i += 4) {
|
||||
initWords[16 + i / 4] = fnv(fnv(fnv(mixWords[i], mixWords[i + 1]), mixWords[i + 2]), mixWords[i + 3]);
|
||||
}
|
||||
|
||||
// final Keccak hashes
|
||||
|
|
@ -179,12 +192,7 @@ exports.Ethash = function(params, seed)
|
|||
return retBytes;
|
||||
};
|
||||
|
||||
this.cacheDigest = function()
|
||||
{
|
||||
this.cacheDigest = function() {
|
||||
return keccak.digest(32, new Uint8Array(cache.buffer));
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
21
Godeps/_workspace/src/github.com/ethereum/ethash/js/package.json
generated
vendored
Normal file
21
Godeps/_workspace/src/github.com/ethereum/ethash/js/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "ethash.js",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "ethash.js",
|
||||
"scripts": {
|
||||
"test": "node ./test/test.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ethereum/ethash/tree/master/js"
|
||||
},
|
||||
"keywords": [
|
||||
"ethereum"
|
||||
],
|
||||
"author": "",
|
||||
"license": "mit",
|
||||
"devDependencies": {
|
||||
"ethereum-tests": "0.0.5"
|
||||
}
|
||||
}
|
||||
48
Godeps/_workspace/src/github.com/ethereum/ethash/js/test/seedHash.js
generated
vendored
Normal file
48
Godeps/_workspace/src/github.com/ethereum/ethash/js/test/seedHash.js
generated
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
var tape = require('tape');
|
||||
const ethash = require('../ethash.js');
|
||||
|
||||
tape('seed hash', function(t) {
|
||||
|
||||
t.test('seed should match TRUTH', function(st) {
|
||||
const seed = '290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563';
|
||||
const blockNum = 30000;
|
||||
|
||||
var r = new Buffer(ethash.calcSeed(blockNum));
|
||||
st.equal(r.toString('hex'), seed);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('seed should match TRUTH2', function(st) {
|
||||
const seed = '510e4e770828ddbf7f7b00ab00a9f6adaf81c0dc9cc85f1f8249c256942d61d9';
|
||||
const blockNum = 60000;
|
||||
|
||||
var r = new Buffer(ethash.calcSeed(blockNum));
|
||||
st.equal(r.toString('hex'), seed);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('seed should match TRUTH3', function(st) {
|
||||
const seed = '510e4e770828ddbf7f7b00ab00a9f6adaf81c0dc9cc85f1f8249c256942d61d9';
|
||||
const blockNum = 60700;
|
||||
|
||||
var r = new Buffer(ethash.calcSeed(blockNum));
|
||||
st.equal(r.toString('hex'), seed);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('randomized tests', function(st) {
|
||||
for (var i = 0; i < 100; i++) {
|
||||
var x = Math.floor(ethash.params.EPOCH_LENGTH * 2048 * Math.random());
|
||||
st.equal(ethash.calcSeed(x).toString('hex'), ethash.calcSeed(Math.floor(x / ethash.params.EPOCH_LENGTH) * ethash.params.EPOCH_LENGTH ).toString('hex'));
|
||||
}
|
||||
st.end();
|
||||
});
|
||||
// '510e4e770828ddbf7f7b00ab00a9f6adaf81c0dc9cc85f1f8249c256942d61d9'
|
||||
// [7:13:32 PM] Matthew Wampler-Doty: >>> x = randint(0,700000)
|
||||
//
|
||||
// >>> pyethash.get_seedhash(x).encode('hex') == pyethash.get_seedhash((x // pyethash.EPOCH_LENGTH) * pyethash.EPOCH_LENGTH).encode('hex')
|
||||
|
||||
});
|
||||
|
|
@ -4,9 +4,9 @@
|
|||
/*jslint node: true, shadow:true */
|
||||
"use strict";
|
||||
|
||||
var ethash = require('./ethash');
|
||||
var util = require('./util');
|
||||
var Keccak = require('./keccak');
|
||||
var ethash = require('../ethash');
|
||||
var util = require('../util');
|
||||
var Keccak = require('../keccak');
|
||||
|
||||
// sanity check hash functions
|
||||
var src = util.stringToBytes("");
|
||||
|
|
@ -31,7 +31,7 @@ var ethashParams = ethash.defaultParams();
|
|||
var seed = util.hexStringToBytes("9410b944535a83d9adf6bbdcc80e051f30676173c16ca0d32d6f1263fc246466")
|
||||
var startTime = new Date().getTime();
|
||||
var hasher = new ethash.Ethash(ethashParams, seed);
|
||||
console.log('Ethash startup took: '+(new Date().getTime() - startTime) + "ms");
|
||||
console.log('Ethash startup took: ' + (new Date().getTime() - startTime) + "ms");
|
||||
console.log('Ethash cache hash: ' + util.bytesToHexString(hasher.cacheDigest()));
|
||||
|
||||
var testHexString = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470";
|
||||
|
|
@ -45,9 +45,8 @@ var hash;
|
|||
|
||||
startTime = new Date().getTime();
|
||||
var trials = 10;
|
||||
for (var i = 0; i < trials; ++i)
|
||||
{
|
||||
for (var i = 0; i < trials; ++i) {
|
||||
hash = hasher.hash(header, nonce);
|
||||
}
|
||||
console.log("Light client hashes averaged: " + (new Date().getTime() - startTime)/trials + "ms");
|
||||
console.log("Light client hashes averaged: " + (new Date().getTime() - startTime) / trials + "ms");
|
||||
console.log("Hash = " + util.bytesToHexString(hash));
|
||||
2
Godeps/_workspace/src/github.com/ethereum/ethash/pyethash/.gitignore
generated
vendored
2
Godeps/_workspace/src/github.com/ethereum/ethash/pyethash/.gitignore
generated
vendored
|
|
@ -1,2 +0,0 @@
|
|||
pyethash.egg-info/
|
||||
*.so
|
||||
3
Godeps/_workspace/src/github.com/ethereum/ethash/pyethash/__init__.py
generated
vendored
3
Godeps/_workspace/src/github.com/ethereum/ethash/pyethash/__init__.py
generated
vendored
|
|
@ -1,3 +0,0 @@
|
|||
import pyethash.core
|
||||
core = pyethash.core
|
||||
EPOCH_LENGTH = 30000
|
||||
22
Godeps/_workspace/src/github.com/ethereum/ethash/setup.py
generated
vendored
22
Godeps/_workspace/src/github.com/ethereum/ethash/setup.py
generated
vendored
|
|
@ -1,21 +1,33 @@
|
|||
#!/usr/bin/env python
|
||||
from distutils.core import setup, Extension
|
||||
|
||||
pyethash_core = Extension('pyethash.core',
|
||||
pyethash = Extension('pyethash',
|
||||
sources = [
|
||||
'src/python/core.c',
|
||||
'src/libethash/util.c',
|
||||
'src/libethash/internal.c',
|
||||
'src/libethash/sha3.c'
|
||||
'src/libethash/sha3.c'],
|
||||
depends = [
|
||||
'src/libethash/ethash.h',
|
||||
'src/libethash/compiler.h',
|
||||
'src/libethash/data_sizes.h',
|
||||
'src/libethash/endian.h',
|
||||
'src/libethash/ethash.h',
|
||||
'src/libethash/fnv.h',
|
||||
'src/libethash/internal.h',
|
||||
'src/libethash/sha3.h',
|
||||
'src/libethash/util.h'
|
||||
],
|
||||
extra_compile_args = ["-std=gnu99"])
|
||||
extra_compile_args = ["-Isrc/", "-std=gnu99", "-Wall"])
|
||||
|
||||
setup (
|
||||
name = 'pyethash',
|
||||
author = "Matthew Wampler-Doty",
|
||||
author_email = "matthew.wampler.doty@gmail.com",
|
||||
license = 'GPL',
|
||||
version = '1.0',
|
||||
version = '23.1',
|
||||
url = 'https://github.com/ethereum/ethash',
|
||||
download_url = 'https://github.com/ethereum/ethash/tarball/v23.1',
|
||||
description = 'Python wrappers for ethash, the ethereum proof of work hashing function',
|
||||
ext_modules = [pyethash_core],
|
||||
ext_modules = [pyethash],
|
||||
)
|
||||
|
|
|
|||
2
Godeps/_workspace/src/github.com/ethereum/ethash/src/benchmark/benchmark.cpp
generated
vendored
2
Godeps/_workspace/src/github.com/ethereum/ethash/src/benchmark/benchmark.cpp
generated
vendored
|
|
@ -31,7 +31,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
#ifdef WITH_CRYPTOPP
|
||||
#include <libethash/SHA3_cryptopp.h>
|
||||
#include <libethash/sha3_cryptopp.h>
|
||||
#include <string>
|
||||
|
||||
#else
|
||||
|
|
|
|||
29
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt
generated
vendored
29
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt
generated
vendored
|
|
@ -2,14 +2,39 @@ set(LIBRARY ethash-cl)
|
|||
set(CMAKE_BUILD_TYPE Release)
|
||||
|
||||
include(bin2h.cmake)
|
||||
bin2h(SOURCE_FILE ethash_cl_miner_kernel.cl VARIABLE_NAME ethash_cl_miner_kernel HEADER_FILE ${CMAKE_CURRENT_BINARY_DIR}/ethash_cl_miner_kernel.h)
|
||||
bin2h(SOURCE_FILE ethash_cl_miner_kernel.cl
|
||||
VARIABLE_NAME ethash_cl_miner_kernel
|
||||
HEADER_FILE ${CMAKE_CURRENT_BINARY_DIR}/ethash_cl_miner_kernel.h)
|
||||
|
||||
if (NOT MSVC)
|
||||
# Initialize CXXFLAGS for c++11
|
||||
set(CMAKE_CXX_FLAGS "-Wall -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
|
||||
|
||||
# Compiler-specific C++11 activation.
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
|
||||
if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
|
||||
message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.")
|
||||
endif ()
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||
else ()
|
||||
message(FATAL_ERROR "Your C++ compiler does not support C++11.")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
if (NOT OpenCL_FOUND)
|
||||
find_package(OpenCL)
|
||||
endif()
|
||||
|
||||
if (OpenCL_FOUND)
|
||||
include_directories(${OpenCL_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(..)
|
||||
add_library(${LIBRARY} ethash_cl_miner.cpp ethash_cl_miner.h)
|
||||
add_library(${LIBRARY} ethash_cl_miner.cpp ethash_cl_miner.h cl.hpp)
|
||||
TARGET_LINK_LIBRARIES(${LIBRARY} ${OpenCL_LIBRARIES} ethash)
|
||||
endif()
|
||||
|
|
|
|||
3
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/bin2h.cmake
generated
vendored
3
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/bin2h.cmake
generated
vendored
|
|
@ -68,8 +68,7 @@ function(BIN2H)
|
|||
string(REGEX REPLACE ", $" "" arrayValues ${arrayValues})
|
||||
|
||||
# converts the variable name into proper C identifier
|
||||
# TODO: fix for legacy cmake
|
||||
IF (${CMAKE_VERSION} GREATER 2.8.10)
|
||||
IF (${CMAKE_VERSION} GREATER 2.8.10) # fix for legacy cmake
|
||||
string(MAKE_C_IDENTIFIER "${BIN2H_VARIABLE_NAME}" BIN2H_VARIABLE_NAME)
|
||||
ENDIF()
|
||||
string(TOUPPER "${BIN2H_VARIABLE_NAME}" BIN2H_VARIABLE_NAME)
|
||||
|
|
|
|||
55
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp
generated
vendored
55
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp
generated
vendored
|
|
@ -24,15 +24,22 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include "ethash_cl_miner.h"
|
||||
#include "ethash_cl_miner_kernel.h"
|
||||
#include <libethash/util.h>
|
||||
|
||||
#define ETHASH_BYTES 32
|
||||
|
||||
// workaround lame platforms
|
||||
#if !CL_VERSION_1_2
|
||||
#define CL_MAP_WRITE_INVALIDATE_REGION CL_MAP_WRITE
|
||||
#define CL_MEM_HOST_READ_ONLY 0
|
||||
#endif
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#define HASH_BYTES 32
|
||||
|
||||
static void add_definition(std::string& source, char const* id, unsigned value)
|
||||
{
|
||||
char buf[256];
|
||||
|
|
@ -41,6 +48,7 @@ static void add_definition(std::string& source, char const* id, unsigned value)
|
|||
}
|
||||
|
||||
ethash_cl_miner::ethash_cl_miner()
|
||||
: m_opencl_1_1()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -71,11 +79,23 @@ bool ethash_cl_miner::init(ethash_params const& params, const uint8_t seed[32],
|
|||
}
|
||||
|
||||
// use default device
|
||||
cl::Device& device = devices[0];
|
||||
debugf("Using device: %s\n", device.getInfo<CL_DEVICE_NAME>().c_str());
|
||||
unsigned device_num = 0;
|
||||
cl::Device& device = devices[device_num];
|
||||
std::string device_version = device.getInfo<CL_DEVICE_VERSION>();
|
||||
debugf("Using device: %s (%s)\n", device.getInfo<CL_DEVICE_NAME>().c_str(),device_version.c_str());
|
||||
|
||||
if (strncmp("OpenCL 1.0", device_version.c_str(), 10) == 0)
|
||||
{
|
||||
debugf("OpenCL 1.0 is not supported.\n");
|
||||
return false;
|
||||
}
|
||||
if (strncmp("OpenCL 1.1", device_version.c_str(), 10) == 0)
|
||||
{
|
||||
m_opencl_1_1 = true;
|
||||
}
|
||||
|
||||
// create context
|
||||
m_context = cl::Context({device});
|
||||
m_context = cl::Context(std::vector<cl::Device>(&device, &device+1));
|
||||
m_queue = cl::CommandQueue(m_context, device);
|
||||
|
||||
// use requested workgroup size, but we require multiple of 8
|
||||
|
|
@ -120,7 +140,7 @@ bool ethash_cl_miner::init(ethash_params const& params, const uint8_t seed[32],
|
|||
ethash_mkcache(&cache, ¶ms, seed);
|
||||
|
||||
// if this throws then it's because we probably need to subdivide the dag uploads for compatibility
|
||||
void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, CL_MAP_WRITE_INVALIDATE_REGION, 0, params.full_size);
|
||||
void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, m_opencl_1_1 ? CL_MAP_WRITE : CL_MAP_WRITE_INVALIDATE_REGION, 0, params.full_size);
|
||||
ethash_compute_full_data(dag_ptr, ¶ms, &cache);
|
||||
m_queue.enqueueUnmapMemObject(m_dag, dag_ptr);
|
||||
|
||||
|
|
@ -130,7 +150,7 @@ bool ethash_cl_miner::init(ethash_params const& params, const uint8_t seed[32],
|
|||
// create mining buffers
|
||||
for (unsigned i = 0; i != c_num_buffers; ++i)
|
||||
{
|
||||
m_hash_buf[i] = cl::Buffer(m_context, CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, 32*c_hash_batch_size);
|
||||
m_hash_buf[i] = cl::Buffer(m_context, CL_MEM_WRITE_ONLY | (!m_opencl_1_1 ? CL_MEM_HOST_READ_ONLY : 0), 32*c_hash_batch_size);
|
||||
m_search_buf[i] = cl::Buffer(m_context, CL_MEM_WRITE_ONLY, (c_max_search_results + 1) * sizeof(uint32_t));
|
||||
}
|
||||
return true;
|
||||
|
|
@ -176,7 +196,6 @@ void ethash_cl_miner::hash(uint8_t* ret, uint8_t const* header, uint64_t nonce,
|
|||
m_hash_kernel.setArg(0, m_hash_buf[buf]);
|
||||
|
||||
// execute it!
|
||||
clock_t start_time = clock();
|
||||
m_queue.enqueueNDRangeKernel(
|
||||
m_hash_kernel,
|
||||
cl::NullRange,
|
||||
|
|
@ -196,8 +215,8 @@ void ethash_cl_miner::hash(uint8_t* ret, uint8_t const* header, uint64_t nonce,
|
|||
pending_batch const& batch = pending.front();
|
||||
|
||||
// could use pinned host pointer instead, but this path isn't that important.
|
||||
uint8_t* hashes = (uint8_t*)m_queue.enqueueMapBuffer(m_hash_buf[batch.buf], true, CL_MAP_READ, 0, batch.count * HASH_BYTES);
|
||||
memcpy(ret + batch.base*HASH_BYTES, hashes, batch.count*HASH_BYTES);
|
||||
uint8_t* hashes = (uint8_t*)m_queue.enqueueMapBuffer(m_hash_buf[batch.buf], true, CL_MAP_READ, 0, batch.count * ETHASH_BYTES);
|
||||
memcpy(ret + batch.base*ETHASH_BYTES, hashes, batch.count*ETHASH_BYTES);
|
||||
m_queue.enqueueUnmapMemObject(m_hash_buf[batch.buf], hashes);
|
||||
|
||||
pending.pop();
|
||||
|
|
@ -223,8 +242,19 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
|
|||
{
|
||||
m_queue.enqueueWriteBuffer(m_search_buf[i], false, 0, 4, &c_zero);
|
||||
}
|
||||
|
||||
#if CL_VERSION_1_2
|
||||
cl::Event pre_return_event;
|
||||
if (!m_opencl_1_1)
|
||||
{
|
||||
m_queue.enqueueBarrierWithWaitList(NULL, &pre_return_event);
|
||||
}
|
||||
else
|
||||
#else
|
||||
{
|
||||
m_queue.finish();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
__kernel void ethash_combined_search(
|
||||
|
|
@ -284,6 +314,11 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook
|
|||
}
|
||||
|
||||
// not safe to return until this is ready
|
||||
#if CL_VERSION_1_2
|
||||
if (!m_opencl_1_1)
|
||||
{
|
||||
pre_return_event.wait();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
1
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h
generated
vendored
1
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h
generated
vendored
|
|
@ -40,4 +40,5 @@ private:
|
|||
cl::Buffer m_hash_buf[c_num_buffers];
|
||||
cl::Buffer m_search_buf[c_num_buffers];
|
||||
unsigned m_workgroup_size;
|
||||
bool m_opencl_1_1;
|
||||
};
|
||||
1
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/CMakeLists.txt
generated
vendored
1
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/CMakeLists.txt
generated
vendored
|
|
@ -2,7 +2,6 @@ set(LIBRARY ethash)
|
|||
|
||||
if (CPPETHEREUM)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
#else ()
|
||||
endif ()
|
||||
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
|
|
|
|||
641
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/data_sizes.h
generated
vendored
641
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/data_sizes.h
generated
vendored
|
|
@ -20,8 +20,6 @@
|
|||
* @date 2015
|
||||
*/
|
||||
|
||||
// TODO: Update this after ~3.5 years
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
|
@ -33,23 +31,24 @@ extern "C" {
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
// 2048 Epochs worth of tabulated DAG sizes
|
||||
// 2048 Epochs (~20 years) worth of tabulated DAG sizes
|
||||
|
||||
// Generated with the following Mathematica Code:
|
||||
|
||||
// GetDataSizes[n_] := Module[{
|
||||
// DataSetSizeBytesInit = 2^30,
|
||||
// MixBytes = 128,
|
||||
// DataSetGrowth = 2^23,
|
||||
// GetCacheSizes[n_] := Module[{
|
||||
// CacheSizeBytesInit = 2^24,
|
||||
// CacheGrowth = 2^17,
|
||||
// HashBytes = 64,
|
||||
// j = 0},
|
||||
// Reap[
|
||||
// While[j < n,
|
||||
// Module[{i =
|
||||
// Floor[(DataSetSizeBytesInit + DataSetGrowth * j) / MixBytes]},
|
||||
// Floor[(CacheSizeBytesInit + CacheGrowth * j) / HashBytes]},
|
||||
// While[! PrimeQ[i], i--];
|
||||
// Sow[i*MixBytes]; j++]]]][[2]][[1]]
|
||||
// Sow[i*HashBytes]; j++]]]][[2]][[1]]
|
||||
|
||||
static const size_t dag_sizes[] = {
|
||||
|
||||
static const uint64_t dag_sizes[2048] = {
|
||||
1073739904U, 1082130304U, 1090514816U, 1098906752U, 1107293056U,
|
||||
1115684224U, 1124070016U, 1132461952U, 1140849536U, 1149232768U,
|
||||
1157627776U, 1166013824U, 1174404736U, 1182786944U, 1191180416U,
|
||||
|
|
@ -478,300 +477,334 @@ static const size_t dag_sizes[] = {
|
|||
// While[! PrimeQ[i], i--];
|
||||
// Sow[i*HashBytes]; j++]]]][[2]][[1]]
|
||||
|
||||
const size_t cache_sizes[] = {
|
||||
1048384U, 1055552U, 1064512U, 1072832U, 1080896U, 1089344U, 1096768U,
|
||||
1104448U, 1113664U, 1121216U, 1130176U, 1138624U, 1146304U, 1155008U,
|
||||
1162816U, 1171264U, 1179328U, 1187392U, 1195456U, 1203392U, 1210816U,
|
||||
1220416U, 1227712U, 1236416U, 1244608U, 1253312U, 1261376U, 1268416U,
|
||||
1277632U, 1285696U, 1294016U, 1302208U, 1310656U, 1318336U, 1326784U,
|
||||
1334848U, 1342912U, 1350848U, 1359808U, 1366208U, 1376192U, 1383488U,
|
||||
1392448U, 1400384U, 1408832U, 1416512U, 1425344U, 1433408U, 1440704U,
|
||||
1449664U, 1458112U, 1466048U, 1474496U, 1482688U, 1490752U, 1498688U,
|
||||
1507136U, 1515328U, 1523264U, 1531456U, 1539904U, 1547584U, 1556288U,
|
||||
1564352U, 1572544U, 1580608U, 1588544U, 1596992U, 1605568U, 1612096U,
|
||||
1621952U, 1630144U, 1637696U, 1645888U, 1654336U, 1662784U, 1671104U,
|
||||
1679168U, 1686848U, 1695296U, 1702208U, 1711168U, 1720256U, 1727552U,
|
||||
1736128U, 1744576U, 1751488U, 1760576U, 1769408U, 1777472U, 1785664U,
|
||||
1793984U, 1801664U, 1810112U, 1818304U, 1826624U, 1834816U, 1842752U,
|
||||
1851328U, 1858112U, 1867456U, 1875904U, 1883968U, 1892288U, 1899712U,
|
||||
1908416U, 1916608U, 1924544U, 1932992U, 1940672U, 1948736U, 1956928U,
|
||||
1965632U, 1973824U, 1982144U, 1989824U, 1998784U, 2006848U, 2014784U,
|
||||
2022848U, 2031424U, 2038976U, 2047424U, 2055616U, 2064064U, 2072384U,
|
||||
2080448U, 2088512U, 2095936U, 2104768U, 2113472U, 2121664U, 2127808U,
|
||||
2137792U, 2146112U, 2153408U, 2162624U, 2170304U, 2178496U, 2186944U,
|
||||
2195392U, 2203456U, 2211136U, 2219968U, 2227648U, 2236096U, 2244416U,
|
||||
2250944U, 2260928U, 2268736U, 2276672U, 2283328U, 2293696U, 2301632U,
|
||||
2309312U, 2317888U, 2325952U, 2334656U, 2342848U, 2350144U, 2358848U,
|
||||
2366656U, 2375488U, 2383552U, 2391616U, 2400064U, 2407616U, 2415808U,
|
||||
2424256U, 2432704U, 2439616U, 2448704U, 2457152U, 2464064U, 2473792U,
|
||||
2482112U, 2489792U, 2497472U, 2506432U, 2514752U, 2522816U, 2531264U,
|
||||
2539456U, 2547136U, 2555456U, 2564032U, 2572096U, 2578496U, 2587712U,
|
||||
2595776U, 2604736U, 2613056U, 2620736U, 2629184U, 2637632U, 2645824U,
|
||||
2653888U, 2662208U, 2670016U, 2678464U, 2686912U, 2694464U, 2703296U,
|
||||
2710976U, 2719424U, 2727104U, 2736064U, 2743232U, 2752192U, 2760512U,
|
||||
2768704U, 2777024U, 2785088U, 2792512U, 2800576U, 2809024U, 2817856U,
|
||||
2826176U, 2833984U, 2840896U, 2850752U, 2858048U, 2867008U, 2875328U,
|
||||
2883392U, 2891584U, 2899648U, 2908096U, 2915648U, 2924224U, 2932672U,
|
||||
2940736U, 2948672U, 2956736U, 2964928U, 2973248U, 2981824U, 2988992U,
|
||||
2997184U, 3005248U, 3013952U, 3022144U, 3030592U, 3037376U, 3046976U,
|
||||
3055552U, 3063616U, 3070784U, 3079744U, 3087808U, 3096512U, 3103808U,
|
||||
3111872U, 3121088U, 3128896U, 3137216U, 3144896U, 3153856U, 3161152U,
|
||||
3169984U, 3178432U, 3186496U, 3194816U, 3203008U, 3210176U, 3218624U,
|
||||
3227072U, 3235264U, 3243712U, 3250496U, 3259456U, 3268544U, 3276736U,
|
||||
3283648U, 3292736U, 3301184U, 3308224U, 3317696U, 3324736U, 3333184U,
|
||||
3342272U, 3348544U, 3357248U, 3365312U, 3374912U, 3383104U, 3390784U,
|
||||
3399488U, 3407296U, 3414976U, 3424192U, 3432256U, 3440576U, 3448768U,
|
||||
3456832U, 3464896U, 3473216U, 3480128U, 3489344U, 3497408U, 3505856U,
|
||||
3514048U, 3521344U, 3530432U, 3538624U, 3546304U, 3555008U, 3563072U,
|
||||
3571648U, 3579712U, 3587392U, 3595456U, 3603904U, 3612352U, 3620416U,
|
||||
3628864U, 3636928U, 3645248U, 3652928U, 3660992U, 3669184U, 3677888U,
|
||||
3685952U, 3694528U, 3702592U, 3710528U, 3719104U, 3727168U, 3735488U,
|
||||
3742784U, 3751232U, 3759424U, 3765184U, 3775808U, 3783872U, 3792832U,
|
||||
3800768U, 3808832U, 3816256U, 3825344U, 3832768U, 3841856U, 3849536U,
|
||||
3857344U, 3866432U, 3874496U, 3882304U, 3890752U, 3899072U, 3907264U,
|
||||
3914816U, 3923008U, 3930688U, 3939904U, 3947968U, 3956416U, 3964736U,
|
||||
3972544U, 3981248U, 3988928U, 3997376U, 4005824U, 4012864U, 4020928U,
|
||||
4030144U, 4038592U, 4045504U, 4054592U, 4063168U, 4071104U, 4079552U,
|
||||
4087232U, 4095808U, 4103872U, 4111168U, 4120384U, 4127936U, 4136512U,
|
||||
4144832U, 4153024U, 4160704U, 4169408U, 4177216U, 4186048U, 4193344U,
|
||||
4202048U, 4210496U, 4217536U, 4227008U, 4235072U, 4243264U, 4251584U,
|
||||
4259392U, 4267712U, 4275776U, 4284352U, 4291904U, 4300096U, 4307648U,
|
||||
4316992U, 4325056U, 4333376U, 4341056U, 4349888U, 4357568U, 4366016U,
|
||||
4374464U, 4382528U, 4390208U, 4398656U, 4407232U, 4413632U, 4423616U,
|
||||
4431808U, 4439744U, 4447936U, 4455872U, 4463296U, 4472128U, 4480576U,
|
||||
4489024U, 4497344U, 4505152U, 4512448U, 4520896U, 4530112U, 4537664U,
|
||||
4546496U, 4554688U, 4562752U, 4570816U, 4579264U, 4586944U, 4595648U,
|
||||
4603712U, 4611392U, 4619072U, 4628032U, 4635584U, 4643776U, 4652864U,
|
||||
4660672U, 4669376U, 4677056U, 4684096U, 4693184U, 4702144U, 4710208U,
|
||||
4718528U, 4726336U, 4734272U, 4742464U, 4750784U, 4759232U, 4767296U,
|
||||
4775872U, 4783808U, 4791872U, 4797376U, 4808512U, 4816192U, 4825024U,
|
||||
4832704U, 4841024U, 4849472U, 4856512U, 4865984U, 4874176U, 4882112U,
|
||||
4889792U, 4898752U, 4906688U, 4913984U, 4922816U, 4931008U, 4938944U,
|
||||
4946624U, 4955584U, 4964032U, 4972096U, 4980032U, 4988864U, 4997056U,
|
||||
5004992U, 5012288U, 5020096U, 5029312U, 5037632U, 5045696U, 5052224U,
|
||||
5062592U, 5070784U, 5078848U, 5086784U, 5095232U, 5100736U, 5111488U,
|
||||
5119936U, 5127104U, 5136064U, 5143616U, 5151424U, 5160256U, 5168704U,
|
||||
5175232U, 5185472U, 5192384U, 5199296U, 5209664U, 5218112U, 5225536U,
|
||||
5233472U, 5242816U, 5250496U, 5258944U, 5267264U, 5274944U, 5283776U,
|
||||
5290048U, 5300032U, 5308096U, 5316544U, 5323328U, 5331904U, 5340736U,
|
||||
5349056U, 5356864U, 5365312U, 5372096U, 5381696U, 5390272U, 5398336U,
|
||||
5405888U, 5413696U, 5422784U, 5430976U, 5439424U, 5446976U, 5455808U,
|
||||
5463616U, 5471168U, 5480128U, 5488064U, 5494592U, 5504704U, 5513152U,
|
||||
5521216U, 5529536U, 5536576U, 5544256U, 5554112U, 5559616U, 5570368U,
|
||||
5577664U, 5586752U, 5594944U, 5603008U, 5611456U, 5619392U, 5627584U,
|
||||
5634368U, 5643328U, 5651264U, 5659328U, 5667008U, 5675584U, 5684416U,
|
||||
5692864U, 5701568U, 5709632U, 5717056U, 5725376U, 5734336U, 5740096U,
|
||||
5750336U, 5758912U, 5766848U, 5775296U, 5782976U, 5790784U, 5799616U,
|
||||
5807936U, 5815232U, 5823808U, 5832256U, 5840192U, 5848768U, 5856832U,
|
||||
5864896U, 5873344U, 5879872U, 5888576U, 5897792U, 5905216U, 5914432U,
|
||||
5920448U, 5930944U, 5938624U, 5947328U, 5955392U, 5963456U, 5971648U,
|
||||
5979328U, 5988032U, 5995712U, 6003904U, 6012736U, 6021056U, 6029248U,
|
||||
6037184U, 6045632U, 6053312U, 6061376U, 6070208U, 6077504U, 6086464U,
|
||||
6094784U, 6101696U, 6110912U, 6118592U, 6127168U, 6135616U, 6143296U,
|
||||
6150208U, 6158912U, 6168128U, 6175808U, 6182464U, 6192832U, 6201152U,
|
||||
6209344U, 6217664U, 6224576U, 6233408U, 6241472U, 6249664U, 6258496U,
|
||||
6266816U, 6275008U, 6281152U, 6291136U, 6299456U, 6306752U, 6314816U,
|
||||
6323776U, 6332096U, 6339392U, 6348224U, 6356288U, 6364096U, 6373184U,
|
||||
6381376U, 6389696U, 6397504U, 6404416U, 6413632U, 6421952U, 6430016U,
|
||||
6437824U, 6446912U, 6454592U, 6463168U, 6471616U, 6478144U, 6487232U,
|
||||
6496192U, 6504128U, 6511936U, 6520256U, 6528832U, 6536896U, 6544576U,
|
||||
6553408U, 6561472U, 6569792U, 6577216U, 6586304U, 6592448U, 6601024U,
|
||||
6610624U, 6619072U, 6627136U, 6634816U, 6643264U, 6650816U, 6659776U,
|
||||
6667712U, 6675904U, 6682688U, 6691904U, 6700864U, 6709184U, 6717376U,
|
||||
6724544U, 6733504U, 6741824U, 6749888U, 6756032U, 6766528U, 6773056U,
|
||||
6782912U, 6790976U, 6798016U, 6807488U, 6815168U, 6823744U, 6832064U,
|
||||
6840128U, 6847552U, 6855872U, 6864064U, 6872128U, 6880576U, 6889408U,
|
||||
6897472U, 6905792U, 6913472U, 6920896U, 6930368U, 6938432U, 6946624U,
|
||||
6953536U, 6963136U, 6971072U, 6979136U, 6986944U, 6995392U, 7003712U,
|
||||
7012288U, 7019072U, 7028416U, 7036352U, 7044416U, 7051712U, 7060672U,
|
||||
7069376U, 7077568U, 7085504U, 7092544U, 7102016U, 7110592U, 7118656U,
|
||||
7126208U, 7135168U, 7143104U, 7150912U, 7159744U, 7167808U, 7175744U,
|
||||
7184192U, 7191232U, 7200448U, 7207744U, 7216576U, 7224128U, 7233472U,
|
||||
7241536U, 7249856U, 7256512U, 7264832U, 7274048U, 7282112U, 7290176U,
|
||||
7298752U, 7306688U, 7315136U, 7322816U, 7331392U, 7339456U, 7347776U,
|
||||
7356224U, 7364288U, 7371712U, 7380928U, 7387456U, 7396544U, 7404352U,
|
||||
7413568U, 7421632U, 7429696U, 7436864U, 7446464U, 7454144U, 7461952U,
|
||||
7470784U, 7478336U, 7487296U, 7495616U, 7503424U, 7511872U, 7520192U,
|
||||
7527616U, 7536448U, 7544512U, 7551424U, 7560128U, 7568576U, 7577536U,
|
||||
7583552U, 7592512U, 7600448U, 7610048U, 7618496U, 7626176U, 7634752U,
|
||||
7642816U, 7651264U, 7659328U, 7667008U, 7675456U, 7683136U, 7691584U,
|
||||
7700416U, 7707584U, 7716416U, 7724224U, 7733056U, 7740608U, 7749184U,
|
||||
7756096U, 7765952U, 7774016U, 7781824U, 7790528U, 7798592U, 7805888U,
|
||||
7814336U, 7822784U, 7831232U, 7839296U, 7847104U, 7855552U, 7863616U,
|
||||
7872448U, 7880128U, 7888576U, 7896256U, 7905088U, 7912768U, 7920448U,
|
||||
7928768U, 7937344U, 7945792U, 7953728U, 7959488U, 7970752U, 7978816U,
|
||||
7987136U, 7994816U, 8003392U, 8011712U, 8019904U, 8027456U, 8035264U,
|
||||
8044352U, 8052544U, 8060224U, 8069056U, 8076736U, 8084672U, 8093504U,
|
||||
8101312U, 8110016U, 8117696U, 8125888U, 8134592U, 8142016U, 8149952U,
|
||||
8159168U, 8166976U, 8175296U, 8183488U, 8191808U, 8199616U, 8207296U,
|
||||
8216128U, 8224576U, 8232256U, 8241088U, 8248256U, 8257472U, 8264128U,
|
||||
8273728U, 8281792U, 8290112U, 8297152U, 8305216U, 8314816U, 8322752U,
|
||||
8330944U, 8339392U, 8347072U, 8355392U, 8363968U, 8371904U, 8379328U,
|
||||
8388544U, 8394944U, 8404544U, 8412736U, 8421184U, 8429504U, 8437696U,
|
||||
8445376U, 8452544U, 8460736U, 8470208U, 8478016U, 8486848U, 8494144U,
|
||||
8503232U, 8511296U, 8519488U, 8527424U, 8534464U, 8543936U, 8552384U,
|
||||
8558912U, 8568128U, 8575936U, 8584256U, 8593216U, 8601536U, 8608832U,
|
||||
8616896U, 8625728U, 8634176U, 8641856U, 8649664U, 8658112U, 8666176U,
|
||||
8674112U, 8682944U, 8691136U, 8699456U, 8707648U, 8716096U, 8724416U,
|
||||
8732608U, 8740672U, 8748352U, 8756032U, 8764864U, 8773568U, 8781376U,
|
||||
8789824U, 8796992U, 8806208U, 8814272U, 8822336U, 8830912U, 8838848U,
|
||||
8847296U, 8854336U, 8863552U, 8871488U, 8879296U, 8887616U, 8894528U,
|
||||
8904512U, 8911424U, 8920768U, 8928704U, 8936128U, 8944576U, 8953664U,
|
||||
8960576U, 8970176U, 8977984U, 8986304U, 8994112U, 9002432U, 9011008U,
|
||||
9018176U, 9026624U, 9035584U, 9043904U, 9052096U, 9059264U, 9068096U,
|
||||
9075904U, 9084224U, 9092288U, 9100352U, 9108928U, 9116992U, 9125824U,
|
||||
9133504U, 9141824U, 9150272U, 9157952U, 9164608U, 9174848U, 9182912U,
|
||||
9190976U, 9199552U, 9205312U, 9215936U, 9222592U, 9232192U, 9240512U,
|
||||
9248704U, 9256256U, 9264832U, 9272896U, 9281344U, 9288896U, 9297088U,
|
||||
9305536U, 9313984U, 9322304U, 9329728U, 9337792U, 9346112U, 9355072U,
|
||||
9363136U, 9371072U, 9378752U, 9387712U, 9395648U, 9404224U, 9411008U,
|
||||
9420608U, 9428416U, 9436864U, 9445312U, 9453376U, 9460928U, 9468736U,
|
||||
9477824U, 9485248U, 9493696U, 9502144U, 9509056U, 9518528U, 9527104U,
|
||||
9535424U, 9543616U, 9551296U, 9559744U, 9568192U, 9576256U, 9584576U,
|
||||
9591872U, 9600704U, 9608384U, 9615808U, 9624512U, 9633472U, 9641536U,
|
||||
9649856U, 9658048U, 9665728U, 9674432U, 9682496U, 9691072U, 9699136U,
|
||||
9707072U, 9715136U, 9722176U, 9732032U, 9740096U, 9747904U, 9756352U,
|
||||
9764288U, 9771584U, 9780544U, 9789376U, 9796928U, 9804224U, 9813952U,
|
||||
9822016U, 9829696U, 9838016U, 9845824U, 9852992U, 9863104U, 9870656U,
|
||||
9878464U, 9887552U, 9895744U, 9903808U, 9912128U, 9920192U, 9927616U,
|
||||
9936064U, 9944768U, 9952576U, 9960128U, 9969472U, 9977152U, 9985216U,
|
||||
9994048U, 10001216U, 10007744U, 10018496U, 10026944U, 10035136U, 10042432U,
|
||||
10051264U, 10059584U, 10067648U, 10075712U, 10083904U, 10091456U, 10100672U,
|
||||
10108864U, 10116928U, 10124864U, 10133056U, 10140736U, 10149824U, 10156736U,
|
||||
10165952U, 10173376U, 10182208U, 10190528U, 10198336U, 10206272U, 10213696U,
|
||||
10223296U, 10231744U, 10238656U, 10247488U, 10256192U, 10263872U, 10272448U,
|
||||
10280896U, 10288448U, 10296512U, 10305088U, 10313536U, 10321088U, 10330048U,
|
||||
10337984U, 10346176U, 10354112U, 10362304U, 10369088U, 10377152U, 10386752U,
|
||||
10394816U, 10403648U, 10411712U, 10418624U, 10427968U, 10436032U, 10444736U,
|
||||
10452928U, 10459712U, 10468672U, 10476608U, 10484416U, 10491328U, 10501952U,
|
||||
10509376U, 10517824U, 10526528U, 10534336U, 10542656U, 10549696U, 10559168U,
|
||||
10566592U, 10575808U, 10583488U, 10590656U, 10599488U, 10607936U, 10616768U,
|
||||
10624832U, 10630336U, 10640576U, 10649536U, 10655168U, 10665152U, 10674112U,
|
||||
10682176U, 10690496U, 10698176U, 10705216U, 10715072U, 10722752U, 10731328U,
|
||||
10739264U, 10746688U, 10754752U, 10761664U, 10770752U, 10779712U, 10787776U,
|
||||
10796608U, 10803392U, 10812352U, 10821056U, 10828736U, 10837952U, 10846144U,
|
||||
10853824U, 10861376U, 10869952U, 10877248U, 10887104U, 10895296U, 10903232U,
|
||||
10910912U, 10918976U, 10927936U, 10935872U, 10944448U, 10952384U, 10960832U,
|
||||
10968512U, 10977088U, 10985024U, 10992832U, 11000896U, 11009984U, 11018048U,
|
||||
11026112U, 11034304U, 11042624U, 11050432U, 11058368U, 11064512U, 11075392U,
|
||||
11083712U, 11091776U, 11099584U, 11107904U, 11115968U, 11124416U, 11131712U,
|
||||
11141056U, 11148608U, 11157184U, 11165248U, 11173312U, 11180992U, 11189056U,
|
||||
11197376U, 11206592U, 11214656U, 11222336U, 11230784U, 11238464U, 11246528U,
|
||||
11254976U, 11263552U, 11271872U, 11279552U, 11288512U, 11296576U, 11304256U,
|
||||
11312192U, 11320768U, 11329216U, 11336384U, 11345216U, 11352512U, 11362112U,
|
||||
11369408U, 11378624U, 11386688U, 11394496U, 11402816U, 11411264U, 11418688U,
|
||||
11427776U, 11435584U, 11444032U, 11452096U, 11459648U, 11467072U, 11476928U,
|
||||
11484992U, 11493184U, 11500352U, 11509312U, 11517248U, 11524928U, 11534144U,
|
||||
11542208U, 11550272U, 11556416U, 11566784U, 11574208U, 11581376U, 11589568U,
|
||||
11599552U, 11607104U, 11616064U, 11623616U, 11632576U, 11639872U, 11648704U,
|
||||
11657024U, 11664704U, 11672896U, 11681216U, 11689792U, 11697856U, 11705536U,
|
||||
11714368U, 11722688U, 11730496U, 11737408U, 11745728U, 11754304U, 11763008U,
|
||||
11770816U, 11779648U, 11788096U, 11795776U, 11804608U, 11812544U, 11820992U,
|
||||
11829184U, 11837248U, 11844928U, 11852096U, 11860928U, 11869888U, 11878336U,
|
||||
11886272U, 11894336U, 11902144U, 11910848U, 11919296U, 11925952U, 11934784U,
|
||||
11943616U, 11951552U, 11960128U, 11968192U, 11976512U, 11983168U, 11992768U,
|
||||
12000832U, 12008896U, 12016832U, 12025408U, 12033856U, 12042176U, 12049984U,
|
||||
12058048U, 12066112U, 12073792U, 12082624U, 12091328U, 12098752U, 12106816U,
|
||||
12115904U, 12124096U, 12131776U, 12140224U, 12148672U, 12156736U, 12164032U,
|
||||
12173248U, 12181184U, 12186176U, 12197824U, 12205888U, 12213952U, 12218944U,
|
||||
12230336U, 12238784U, 12246592U, 12254272U, 12262336U, 12269888U, 12279104U,
|
||||
12287936U, 12295744U, 12304064U, 12312512U, 12319936U, 12328768U, 12337088U,
|
||||
12344896U, 12352832U, 12361408U, 12368704U, 12377152U, 12384832U, 12394432U,
|
||||
12402496U, 12409024U, 12417728U, 12426688U, 12433216U, 12443584U, 12450752U,
|
||||
12459968U, 12468032U, 12475712U, 12484544U, 12492608U, 12500416U, 12508352U,
|
||||
12517184U, 12525376U, 12532288U, 12541888U, 12549568U, 12556864U, 12565568U,
|
||||
12574528U, 12582208U, 12590528U, 12598592U, 12607424U, 12615488U, 12623552U,
|
||||
12631744U, 12638656U, 12647744U, 12656576U, 12664768U, 12672832U, 12680896U,
|
||||
12688576U, 12697408U, 12704192U, 12713408U, 12721216U, 12729664U, 12738496U,
|
||||
12745792U, 12754496U, 12762688U, 12769472U, 12779456U, 12787648U, 12795712U,
|
||||
12804032U, 12812224U, 12819008U, 12828352U, 12836672U, 12844736U, 12851648U,
|
||||
12859456U, 12868672U, 12877504U, 12885568U, 12892864U, 12902336U, 12909376U,
|
||||
12918208U, 12926656U, 12934976U, 12942784U, 12951104U, 12959552U, 12967744U,
|
||||
12976064U, 12984256U, 12991936U, 12999488U, 13007936U, 13016768U, 13021504U,
|
||||
13033024U, 13041472U, 13049408U, 13057472U, 13065664U, 13072064U, 13081408U,
|
||||
13089344U, 13098688U, 13107008U, 13115072U, 13122752U, 13130944U, 13139648U,
|
||||
13147712U, 13155776U, 13162432U, 13172672U, 13180864U, 13188928U, 13196992U,
|
||||
13203392U, 13213504U, 13219264U, 13228736U, 13236928U, 13244992U, 13253056U,
|
||||
13262528U, 13269952U, 13278784U, 13285952U, 13295552U, 13303616U, 13311808U,
|
||||
13319744U, 13328192U, 13336256U, 13344704U, 13352384U, 13360576U, 13369024U,
|
||||
13377344U, 13385408U, 13393216U, 13401664U, 13410112U, 13418176U, 13426496U,
|
||||
13434688U, 13442368U, 13451072U, 13459136U, 13466944U, 13475648U, 13482944U,
|
||||
13491904U, 13500352U, 13508288U, 13516736U, 13524416U, 13532224U, 13541312U,
|
||||
13549504U, 13556288U, 13564736U, 13573184U, 13581376U, 13587008U, 13598656U,
|
||||
13605952U, 13612864U, 13622464U, 13631168U, 13639616U, 13647808U, 13655104U,
|
||||
13663424U, 13671872U, 13680064U, 13688768U, 13696576U, 13705024U, 13712576U,
|
||||
13721536U, 13729216U, 13737664U, 13746112U, 13753024U, 13759552U, 13770304U,
|
||||
13777856U, 13786688U, 13793984U, 13802176U, 13811264U, 13819328U, 13827904U,
|
||||
13835456U, 13844416U, 13851584U, 13860544U, 13868992U, 13877056U, 13884608U,
|
||||
13893184U, 13901248U, 13909696U, 13917632U, 13925056U, 13934528U, 13942336U,
|
||||
13950784U, 13959104U, 13966912U, 13975232U, 13982656U, 13991872U, 13999936U,
|
||||
14007872U, 14016064U, 14024512U, 14032064U, 14040896U, 14049088U, 14057408U,
|
||||
14065088U, 14072896U, 14081344U, 14089664U, 14097856U, 14106304U, 14114752U,
|
||||
14122688U, 14130752U, 14138816U, 14147008U, 14155072U, 14163904U, 14170432U,
|
||||
14180288U, 14187328U, 14196032U, 14204864U, 14212672U, 14220736U, 14229056U,
|
||||
14237504U, 14245568U, 14253632U, 14261824U, 14269888U, 14278592U, 14286656U,
|
||||
14293696U, 14302784U, 14309696U, 14317504U, 14326336U, 14335936U, 14343232U,
|
||||
14352064U, 14359232U, 14368064U, 14376512U, 14384576U, 14393024U, 14401472U,
|
||||
14409536U, 14416832U, 14424512U, 14433856U, 14440768U, 14449984U, 14458816U,
|
||||
14465728U, 14474816U, 14482112U, 14491328U, 14499392U, 14506816U, 14516032U,
|
||||
14524352U, 14531392U, 14540224U, 14547392U, 14556992U, 14565184U, 14573248U,
|
||||
14580928U, 14588864U, 14596928U, 14606272U, 14613824U, 14622656U, 14630464U,
|
||||
14638912U, 14646976U, 14655296U, 14661952U, 14671808U, 14679872U, 14687936U,
|
||||
14696384U, 14704576U, 14710336U, 14720192U, 14729152U, 14736448U, 14745152U,
|
||||
14752448U, 14761792U, 14769856U, 14777024U, 14785984U, 14792384U, 14802752U,
|
||||
14810816U, 14819264U, 14827328U, 14835136U, 14843072U, 14851264U, 14860096U,
|
||||
14867648U, 14876096U, 14884544U, 14892736U, 14900672U, 14907968U, 14917312U,
|
||||
14924864U, 14933824U, 14939968U, 14950336U, 14957632U, 14966464U, 14974912U,
|
||||
14982592U, 14991296U, 14999104U, 15006272U, 15015232U, 15023936U, 15031616U,
|
||||
15040448U, 15047488U, 15055552U, 15063616U, 15073216U, 15079744U, 15088064U,
|
||||
15097664U, 15105344U, 15113792U, 15122368U, 15130048U, 15137728U, 15146176U,
|
||||
15154112U, 15162688U, 15171392U, 15179456U, 15187264U, 15194176U, 15204032U,
|
||||
15212224U, 15220544U, 15227456U, 15237056U, 15245248U, 15253184U, 15261632U,
|
||||
15269824U, 15277376U, 15285824U, 15293888U, 15301568U, 15310784U, 15318848U,
|
||||
15325504U, 15335104U, 15343168U, 15350848U, 15359936U, 15367232U, 15373376U,
|
||||
15384256U, 15392576U, 15400384U, 15408832U, 15417152U, 15424832U, 15433024U,
|
||||
15441344U, 15449152U, 15457088U, 15466432U, 15474112U, 15482816U, 15488576U,
|
||||
15499072U, 15505856U, 15514816U, 15523264U, 15531584U, 15540032U, 15547328U,
|
||||
15553984U, 15564608U, 15571904U, 15579968U, 15589312U, 15597376U, 15605696U,
|
||||
15612992U, 15621824U, 15630016U, 15638464U, 15646144U, 15654592U, 15662912U,
|
||||
15671104U, 15677248U, 15686848U, 15693376U, 15701696U, 15712064U, 15720256U,
|
||||
15728576U, 15736384U, 15744704U, 15752512U, 15761344U, 15769024U, 15777728U,
|
||||
15785152U, 15793984U, 15802048U, 15809984U, 15817024U, 15825856U, 15834944U,
|
||||
15843008U, 15849664U, 15859136U, 15866432U, 15876032U, 15884096U, 15892288U,
|
||||
15900608U, 15908416U, 15916864U, 15924928U, 15930176U, 15941056U, 15949504U,
|
||||
15957824U, 15965632U, 15973952U, 15982528U, 15990592U, 15998272U, 16006976U,
|
||||
16012736U, 16023104U, 16031296U, 16039616U, 16048064U, 16055744U, 16064192U,
|
||||
16071488U, 16080832U, 16088768U, 16097216U, 16104896U, 16112704U, 16121792U,
|
||||
16129856U, 16138048U, 16146112U, 16154176U, 16162624U, 16170688U, 16177856U,
|
||||
16186816U, 16195136U, 16202176U, 16211648U, 16220096U, 16228288U, 16235584U,
|
||||
16244672U, 16252864U, 16260544U, 16269248U, 16277056U, 16285504U, 16291648U,
|
||||
16301632U, 16309312U, 16318144U, 16326208U, 16333888U, 16342336U, 16351168U,
|
||||
16359232U, 16367552U, 16375616U, 16383296U, 16391744U, 16398016U, 16407616U,
|
||||
16415936U, 16424896U, 16432448U, 16440896U, 16449088U, 16457024U, 16465472U,
|
||||
16474048U, 16481216U, 16490048U, 16498624U, 16505792U, 16513984U, 16523072U,
|
||||
16531136U, 16538944U, 16547264U, 16555328U, 16563776U, 16570816U, 16578112U,
|
||||
16587712U, 16596544U, 16604992U, 16613312U, 16620608U, 16629568U, 16637888U,
|
||||
16645696U, 16653632U, 16661696U, 16669888U, 16677568U, 16686272U, 16695232U,
|
||||
16703168U, 16710464U, 16719424U, 16726592U, 16733888U, 16744384U, 16752448U,
|
||||
16760768U, 16768448U, 16776896U, 16785344U, 16793536U, 16801216U, 16809664U,
|
||||
16818112U, 16826176U, 16833472U, 16842688U, 16850752U, 16859072U, 16866368U,
|
||||
16875328U, 16883392U, 16891712U, 16899776U, 16907456U, 16915264U, 16924352U,
|
||||
16931776U, 16940608U, 16949056U, 16957376U, 16965056U, 16973248U, 16981696U,
|
||||
16990144U, 16997056U, 17005888U, 17014208U, 17021504U, 17031104U, 17039296U,
|
||||
17046976U, 17055424U, 17062592U, 17070016U, 17079488U, 17087936U, 17096512U,
|
||||
17104576U, 17113024U, 17121088U, 17129408U, 17136832U, 17145664U, 17152832U,
|
||||
17161792U, 17170112U, 17177792U, 17186368U, 17194304U, 17202496U, 17211328U,
|
||||
17218624U, 17227712U, 17233984U, 17243584U, 17251904U, 17259712U, 17266624U,
|
||||
17276608U, 17284672U, 17292224U, 17301056U, 17309632U, 17317568U, 17326016U,
|
||||
17333824U, 17342272U, 17350208U, 17358784U, 17366848U, 17374912U, 17382592U,
|
||||
17390656U, 17399488U, 17406784U, 17413952U, 17423936U, 17432512U, 17440448U,
|
||||
17447744U, 17456704U, 17464768U, 17472064U, 17481536U, 17489344U, 17495488U,
|
||||
17505728U, 17513792U, 17522368U, 17530816U, 17538112U, 17546944U, 17555264U,
|
||||
17563072U, 17569856U, 17579456U, 17587904U, 17596352U, 17603776U, 17611712U,
|
||||
17620672U, 17628992U, 17637184U, 17645504U, 17653568U, 17661632U, 17669824U,
|
||||
17677376U, 17686208U, 17693888U, 17702336U, 17710144U, 17718208U, 17726528U,
|
||||
17734336U, 17743808U, 17751872U, 17759936U, 17766592U, 17776448U, 17784512U,
|
||||
17791936U, 17801152U, 17809216U, 17817152U
|
||||
const uint64_t cache_sizes[2048] = {
|
||||
16776896U, 16907456U, 17039296U, 17170112U, 17301056U, 17432512U, 17563072U,
|
||||
17693888U, 17824192U, 17955904U, 18087488U, 18218176U, 18349504U, 18481088U,
|
||||
18611392U, 18742336U, 18874304U, 19004224U, 19135936U, 19267264U, 19398208U,
|
||||
19529408U, 19660096U, 19791424U, 19922752U, 20053952U, 20184896U, 20315968U,
|
||||
20446912U, 20576576U, 20709184U, 20840384U, 20971072U, 21102272U, 21233216U,
|
||||
21364544U, 21494848U, 21626816U, 21757376U, 21887552U, 22019392U, 22151104U,
|
||||
22281536U, 22412224U, 22543936U, 22675264U, 22806464U, 22935872U, 23068096U,
|
||||
23198272U, 23330752U, 23459008U, 23592512U, 23723968U, 23854912U, 23986112U,
|
||||
24116672U, 24247616U, 24378688U, 24509504U, 24640832U, 24772544U, 24903488U,
|
||||
25034432U, 25165376U, 25296704U, 25427392U, 25558592U, 25690048U, 25820096U,
|
||||
25951936U, 26081728U, 26214208U, 26345024U, 26476096U, 26606656U, 26737472U,
|
||||
26869184U, 26998208U, 27131584U, 27262528U, 27393728U, 27523904U, 27655744U,
|
||||
27786688U, 27917888U, 28049344U, 28179904U, 28311488U, 28441792U, 28573504U,
|
||||
28700864U, 28835648U, 28966208U, 29096768U, 29228608U, 29359808U, 29490752U,
|
||||
29621824U, 29752256U, 29882816U, 30014912U, 30144448U, 30273728U, 30406976U,
|
||||
30538432U, 30670784U, 30799936U, 30932672U, 31063744U, 31195072U, 31325248U,
|
||||
31456192U, 31588288U, 31719232U, 31850432U, 31981504U, 32110784U, 32243392U,
|
||||
32372672U, 32505664U, 32636608U, 32767808U, 32897344U, 33029824U, 33160768U,
|
||||
33289664U, 33423296U, 33554368U, 33683648U, 33816512U, 33947456U, 34076992U,
|
||||
34208704U, 34340032U, 34471744U, 34600256U, 34734016U, 34864576U, 34993984U,
|
||||
35127104U, 35258176U, 35386688U, 35518528U, 35650624U, 35782336U, 35910976U,
|
||||
36044608U, 36175808U, 36305728U, 36436672U, 36568384U, 36699968U, 36830656U,
|
||||
36961984U, 37093312U, 37223488U, 37355072U, 37486528U, 37617472U, 37747904U,
|
||||
37879232U, 38009792U, 38141888U, 38272448U, 38403392U, 38535104U, 38660672U,
|
||||
38795584U, 38925632U, 39059264U, 39190336U, 39320768U, 39452096U, 39581632U,
|
||||
39713984U, 39844928U, 39974848U, 40107968U, 40238144U, 40367168U, 40500032U,
|
||||
40631744U, 40762816U, 40894144U, 41023552U, 41155904U, 41286208U, 41418304U,
|
||||
41547712U, 41680448U, 41811904U, 41942848U, 42073792U, 42204992U, 42334912U,
|
||||
42467008U, 42597824U, 42729152U, 42860096U, 42991552U, 43122368U, 43253696U,
|
||||
43382848U, 43515712U, 43646912U, 43777088U, 43907648U, 44039104U, 44170432U,
|
||||
44302144U, 44433344U, 44564288U, 44694976U, 44825152U, 44956864U, 45088448U,
|
||||
45219008U, 45350464U, 45481024U, 45612608U, 45744064U, 45874496U, 46006208U,
|
||||
46136768U, 46267712U, 46399424U, 46529344U, 46660672U, 46791488U, 46923328U,
|
||||
47053504U, 47185856U, 47316928U, 47447872U, 47579072U, 47710144U, 47839936U,
|
||||
47971648U, 48103232U, 48234176U, 48365248U, 48496192U, 48627136U, 48757312U,
|
||||
48889664U, 49020736U, 49149248U, 49283008U, 49413824U, 49545152U, 49675712U,
|
||||
49807168U, 49938368U, 50069056U, 50200256U, 50331584U, 50462656U, 50593472U,
|
||||
50724032U, 50853952U, 50986048U, 51117632U, 51248576U, 51379904U, 51510848U,
|
||||
51641792U, 51773248U, 51903296U, 52035136U, 52164032U, 52297664U, 52427968U,
|
||||
52557376U, 52690112U, 52821952U, 52952896U, 53081536U, 53213504U, 53344576U,
|
||||
53475776U, 53608384U, 53738816U, 53870528U, 54000832U, 54131776U, 54263744U,
|
||||
54394688U, 54525248U, 54655936U, 54787904U, 54918592U, 55049152U, 55181248U,
|
||||
55312064U, 55442752U, 55574336U, 55705024U, 55836224U, 55967168U, 56097856U,
|
||||
56228672U, 56358592U, 56490176U, 56621888U, 56753728U, 56884928U, 57015488U,
|
||||
57146816U, 57278272U, 57409216U, 57540416U, 57671104U, 57802432U, 57933632U,
|
||||
58064576U, 58195264U, 58326976U, 58457408U, 58588864U, 58720192U, 58849984U,
|
||||
58981696U, 59113024U, 59243456U, 59375552U, 59506624U, 59637568U, 59768512U,
|
||||
59897792U, 60030016U, 60161984U, 60293056U, 60423872U, 60554432U, 60683968U,
|
||||
60817216U, 60948032U, 61079488U, 61209664U, 61341376U, 61471936U, 61602752U,
|
||||
61733696U, 61865792U, 61996736U, 62127808U, 62259136U, 62389568U, 62520512U,
|
||||
62651584U, 62781632U, 62910784U, 63045056U, 63176128U, 63307072U, 63438656U,
|
||||
63569216U, 63700928U, 63831616U, 63960896U, 64093888U, 64225088U, 64355392U,
|
||||
64486976U, 64617664U, 64748608U, 64879424U, 65009216U, 65142464U, 65273792U,
|
||||
65402816U, 65535424U, 65666752U, 65797696U, 65927744U, 66060224U, 66191296U,
|
||||
66321344U, 66453056U, 66584384U, 66715328U, 66846656U, 66977728U, 67108672U,
|
||||
67239104U, 67370432U, 67501888U, 67631296U, 67763776U, 67895104U, 68026304U,
|
||||
68157248U, 68287936U, 68419264U, 68548288U, 68681408U, 68811968U, 68942912U,
|
||||
69074624U, 69205568U, 69337024U, 69467584U, 69599168U, 69729472U, 69861184U,
|
||||
69989824U, 70122944U, 70253888U, 70385344U, 70515904U, 70647232U, 70778816U,
|
||||
70907968U, 71040832U, 71171648U, 71303104U, 71432512U, 71564992U, 71695168U,
|
||||
71826368U, 71958464U, 72089536U, 72219712U, 72350144U, 72482624U, 72613568U,
|
||||
72744512U, 72875584U, 73006144U, 73138112U, 73268672U, 73400128U, 73530944U,
|
||||
73662272U, 73793344U, 73924544U, 74055104U, 74185792U, 74316992U, 74448832U,
|
||||
74579392U, 74710976U, 74841664U, 74972864U, 75102784U, 75233344U, 75364544U,
|
||||
75497024U, 75627584U, 75759296U, 75890624U, 76021696U, 76152256U, 76283072U,
|
||||
76414144U, 76545856U, 76676672U, 76806976U, 76937792U, 77070016U, 77200832U,
|
||||
77331392U, 77462464U, 77593664U, 77725376U, 77856448U, 77987776U, 78118336U,
|
||||
78249664U, 78380992U, 78511424U, 78642496U, 78773056U, 78905152U, 79033664U,
|
||||
79166656U, 79297472U, 79429568U, 79560512U, 79690816U, 79822784U, 79953472U,
|
||||
80084672U, 80214208U, 80346944U, 80477632U, 80608576U, 80740288U, 80870848U,
|
||||
81002048U, 81133504U, 81264448U, 81395648U, 81525952U, 81657536U, 81786304U,
|
||||
81919808U, 82050112U, 82181312U, 82311616U, 82443968U, 82573376U, 82705984U,
|
||||
82835776U, 82967744U, 83096768U, 83230528U, 83359552U, 83491264U, 83622464U,
|
||||
83753536U, 83886016U, 84015296U, 84147776U, 84277184U, 84409792U, 84540608U,
|
||||
84672064U, 84803008U, 84934336U, 85065152U, 85193792U, 85326784U, 85458496U,
|
||||
85589312U, 85721024U, 85851968U, 85982656U, 86112448U, 86244416U, 86370112U,
|
||||
86506688U, 86637632U, 86769344U, 86900672U, 87031744U, 87162304U, 87293632U,
|
||||
87424576U, 87555392U, 87687104U, 87816896U, 87947968U, 88079168U, 88211264U,
|
||||
88341824U, 88473152U, 88603712U, 88735424U, 88862912U, 88996672U, 89128384U,
|
||||
89259712U, 89390272U, 89521984U, 89652544U, 89783872U, 89914816U, 90045376U,
|
||||
90177088U, 90307904U, 90438848U, 90569152U, 90700096U, 90832832U, 90963776U,
|
||||
91093696U, 91223744U, 91356992U, 91486784U, 91618496U, 91749824U, 91880384U,
|
||||
92012224U, 92143552U, 92273344U, 92405696U, 92536768U, 92666432U, 92798912U,
|
||||
92926016U, 93060544U, 93192128U, 93322816U, 93453632U, 93583936U, 93715136U,
|
||||
93845056U, 93977792U, 94109504U, 94240448U, 94371776U, 94501184U, 94632896U,
|
||||
94764224U, 94895552U, 95023424U, 95158208U, 95287744U, 95420224U, 95550016U,
|
||||
95681216U, 95811904U, 95943872U, 96075328U, 96203584U, 96337856U, 96468544U,
|
||||
96599744U, 96731072U, 96860992U, 96992576U, 97124288U, 97254848U, 97385536U,
|
||||
97517248U, 97647808U, 97779392U, 97910464U, 98041408U, 98172608U, 98303168U,
|
||||
98434496U, 98565568U, 98696768U, 98827328U, 98958784U, 99089728U, 99220928U,
|
||||
99352384U, 99482816U, 99614272U, 99745472U, 99876416U, 100007104U,
|
||||
100138048U, 100267072U, 100401088U, 100529984U, 100662592U, 100791872U,
|
||||
100925248U, 101056064U, 101187392U, 101317952U, 101449408U, 101580608U,
|
||||
101711296U, 101841728U, 101973824U, 102104896U, 102235712U, 102366016U,
|
||||
102498112U, 102628672U, 102760384U, 102890432U, 103021888U, 103153472U,
|
||||
103284032U, 103415744U, 103545152U, 103677248U, 103808576U, 103939648U,
|
||||
104070976U, 104201792U, 104332736U, 104462528U, 104594752U, 104725952U,
|
||||
104854592U, 104988608U, 105118912U, 105247808U, 105381184U, 105511232U,
|
||||
105643072U, 105774784U, 105903296U, 106037056U, 106167872U, 106298944U,
|
||||
106429504U, 106561472U, 106691392U, 106822592U, 106954304U, 107085376U,
|
||||
107216576U, 107346368U, 107478464U, 107609792U, 107739712U, 107872192U,
|
||||
108003136U, 108131392U, 108265408U, 108396224U, 108527168U, 108657344U,
|
||||
108789568U, 108920384U, 109049792U, 109182272U, 109312576U, 109444928U,
|
||||
109572928U, 109706944U, 109837888U, 109969088U, 110099648U, 110230976U,
|
||||
110362432U, 110492992U, 110624704U, 110755264U, 110886208U, 111017408U,
|
||||
111148864U, 111279296U, 111410752U, 111541952U, 111673024U, 111803456U,
|
||||
111933632U, 112066496U, 112196416U, 112328512U, 112457792U, 112590784U,
|
||||
112715968U, 112852672U, 112983616U, 113114944U, 113244224U, 113376448U,
|
||||
113505472U, 113639104U, 113770304U, 113901376U, 114031552U, 114163264U,
|
||||
114294592U, 114425536U, 114556864U, 114687424U, 114818624U, 114948544U,
|
||||
115080512U, 115212224U, 115343296U, 115473472U, 115605184U, 115736128U,
|
||||
115867072U, 115997248U, 116128576U, 116260288U, 116391488U, 116522944U,
|
||||
116652992U, 116784704U, 116915648U, 117046208U, 117178304U, 117308608U,
|
||||
117440192U, 117569728U, 117701824U, 117833024U, 117964096U, 118094656U,
|
||||
118225984U, 118357312U, 118489024U, 118617536U, 118749632U, 118882112U,
|
||||
119012416U, 119144384U, 119275328U, 119406016U, 119537344U, 119668672U,
|
||||
119798464U, 119928896U, 120061376U, 120192832U, 120321728U, 120454336U,
|
||||
120584512U, 120716608U, 120848192U, 120979136U, 121109056U, 121241408U,
|
||||
121372352U, 121502912U, 121634752U, 121764416U, 121895744U, 122027072U,
|
||||
122157632U, 122289088U, 122421184U, 122550592U, 122682944U, 122813888U,
|
||||
122945344U, 123075776U, 123207488U, 123338048U, 123468736U, 123600704U,
|
||||
123731264U, 123861952U, 123993664U, 124124608U, 124256192U, 124386368U,
|
||||
124518208U, 124649024U, 124778048U, 124911296U, 125041088U, 125173696U,
|
||||
125303744U, 125432896U, 125566912U, 125696576U, 125829056U, 125958592U,
|
||||
126090304U, 126221248U, 126352832U, 126483776U, 126615232U, 126746432U,
|
||||
126876608U, 127008704U, 127139392U, 127270336U, 127401152U, 127532224U,
|
||||
127663552U, 127794752U, 127925696U, 128055232U, 128188096U, 128319424U,
|
||||
128449856U, 128581312U, 128712256U, 128843584U, 128973632U, 129103808U,
|
||||
129236288U, 129365696U, 129498944U, 129629888U, 129760832U, 129892288U,
|
||||
130023104U, 130154048U, 130283968U, 130416448U, 130547008U, 130678336U,
|
||||
130807616U, 130939456U, 131071552U, 131202112U, 131331776U, 131464384U,
|
||||
131594048U, 131727296U, 131858368U, 131987392U, 132120256U, 132250816U,
|
||||
132382528U, 132513728U, 132644672U, 132774976U, 132905792U, 133038016U,
|
||||
133168832U, 133299392U, 133429312U, 133562048U, 133692992U, 133823296U,
|
||||
133954624U, 134086336U, 134217152U, 134348608U, 134479808U, 134607296U,
|
||||
134741056U, 134872384U, 135002944U, 135134144U, 135265472U, 135396544U,
|
||||
135527872U, 135659072U, 135787712U, 135921472U, 136052416U, 136182848U,
|
||||
136313792U, 136444864U, 136576448U, 136707904U, 136837952U, 136970048U,
|
||||
137099584U, 137232064U, 137363392U, 137494208U, 137625536U, 137755712U,
|
||||
137887424U, 138018368U, 138149824U, 138280256U, 138411584U, 138539584U,
|
||||
138672832U, 138804928U, 138936128U, 139066688U, 139196864U, 139328704U,
|
||||
139460032U, 139590208U, 139721024U, 139852864U, 139984576U, 140115776U,
|
||||
140245696U, 140376512U, 140508352U, 140640064U, 140769856U, 140902336U,
|
||||
141032768U, 141162688U, 141294016U, 141426496U, 141556544U, 141687488U,
|
||||
141819584U, 141949888U, 142080448U, 142212544U, 142342336U, 142474432U,
|
||||
142606144U, 142736192U, 142868288U, 142997824U, 143129408U, 143258944U,
|
||||
143392448U, 143523136U, 143653696U, 143785024U, 143916992U, 144045632U,
|
||||
144177856U, 144309184U, 144440768U, 144570688U, 144701888U, 144832448U,
|
||||
144965056U, 145096384U, 145227584U, 145358656U, 145489856U, 145620928U,
|
||||
145751488U, 145883072U, 146011456U, 146144704U, 146275264U, 146407232U,
|
||||
146538176U, 146668736U, 146800448U, 146931392U, 147062336U, 147193664U,
|
||||
147324224U, 147455936U, 147586624U, 147717056U, 147848768U, 147979456U,
|
||||
148110784U, 148242368U, 148373312U, 148503232U, 148635584U, 148766144U,
|
||||
148897088U, 149028416U, 149159488U, 149290688U, 149420224U, 149551552U,
|
||||
149683136U, 149814976U, 149943616U, 150076352U, 150208064U, 150338624U,
|
||||
150470464U, 150600256U, 150732224U, 150862784U, 150993088U, 151125952U,
|
||||
151254976U, 151388096U, 151519168U, 151649728U, 151778752U, 151911104U,
|
||||
152042944U, 152174144U, 152304704U, 152435648U, 152567488U, 152698816U,
|
||||
152828992U, 152960576U, 153091648U, 153222976U, 153353792U, 153484096U,
|
||||
153616192U, 153747008U, 153878336U, 154008256U, 154139968U, 154270912U,
|
||||
154402624U, 154533824U, 154663616U, 154795712U, 154926272U, 155057984U,
|
||||
155188928U, 155319872U, 155450816U, 155580608U, 155712064U, 155843392U,
|
||||
155971136U, 156106688U, 156237376U, 156367424U, 156499264U, 156630976U,
|
||||
156761536U, 156892352U, 157024064U, 157155008U, 157284416U, 157415872U,
|
||||
157545536U, 157677248U, 157810496U, 157938112U, 158071744U, 158203328U,
|
||||
158334656U, 158464832U, 158596288U, 158727616U, 158858048U, 158988992U,
|
||||
159121216U, 159252416U, 159381568U, 159513152U, 159645632U, 159776192U,
|
||||
159906496U, 160038464U, 160169536U, 160300352U, 160430656U, 160563008U,
|
||||
160693952U, 160822208U, 160956352U, 161086784U, 161217344U, 161349184U,
|
||||
161480512U, 161611456U, 161742272U, 161873216U, 162002752U, 162135872U,
|
||||
162266432U, 162397888U, 162529216U, 162660032U, 162790976U, 162922048U,
|
||||
163052096U, 163184576U, 163314752U, 163446592U, 163577408U, 163707968U,
|
||||
163839296U, 163969984U, 164100928U, 164233024U, 164364224U, 164494912U,
|
||||
164625856U, 164756672U, 164887616U, 165019072U, 165150016U, 165280064U,
|
||||
165412672U, 165543104U, 165674944U, 165805888U, 165936832U, 166067648U,
|
||||
166198336U, 166330048U, 166461248U, 166591552U, 166722496U, 166854208U,
|
||||
166985408U, 167116736U, 167246656U, 167378368U, 167508416U, 167641024U,
|
||||
167771584U, 167903168U, 168034112U, 168164032U, 168295744U, 168427456U,
|
||||
168557632U, 168688448U, 168819136U, 168951616U, 169082176U, 169213504U,
|
||||
169344832U, 169475648U, 169605952U, 169738048U, 169866304U, 169999552U,
|
||||
170131264U, 170262464U, 170393536U, 170524352U, 170655424U, 170782016U,
|
||||
170917696U, 171048896U, 171179072U, 171310784U, 171439936U, 171573184U,
|
||||
171702976U, 171835072U, 171966272U, 172097216U, 172228288U, 172359232U,
|
||||
172489664U, 172621376U, 172747712U, 172883264U, 173014208U, 173144512U,
|
||||
173275072U, 173407424U, 173539136U, 173669696U, 173800768U, 173931712U,
|
||||
174063424U, 174193472U, 174325696U, 174455744U, 174586816U, 174718912U,
|
||||
174849728U, 174977728U, 175109696U, 175242688U, 175374272U, 175504832U,
|
||||
175636288U, 175765696U, 175898432U, 176028992U, 176159936U, 176291264U,
|
||||
176422592U, 176552512U, 176684864U, 176815424U, 176946496U, 177076544U,
|
||||
177209152U, 177340096U, 177470528U, 177600704U, 177731648U, 177864256U,
|
||||
177994816U, 178126528U, 178257472U, 178387648U, 178518464U, 178650176U,
|
||||
178781888U, 178912064U, 179044288U, 179174848U, 179305024U, 179436736U,
|
||||
179568448U, 179698496U, 179830208U, 179960512U, 180092608U, 180223808U,
|
||||
180354752U, 180485696U, 180617152U, 180748096U, 180877504U, 181009984U,
|
||||
181139264U, 181272512U, 181402688U, 181532608U, 181663168U, 181795136U,
|
||||
181926592U, 182057536U, 182190016U, 182320192U, 182451904U, 182582336U,
|
||||
182713792U, 182843072U, 182976064U, 183107264U, 183237056U, 183368384U,
|
||||
183494848U, 183631424U, 183762752U, 183893824U, 184024768U, 184154816U,
|
||||
184286656U, 184417984U, 184548928U, 184680128U, 184810816U, 184941248U,
|
||||
185072704U, 185203904U, 185335616U, 185465408U, 185596352U, 185727296U,
|
||||
185859904U, 185989696U, 186121664U, 186252992U, 186383552U, 186514112U,
|
||||
186645952U, 186777152U, 186907328U, 187037504U, 187170112U, 187301824U,
|
||||
187429184U, 187562048U, 187693504U, 187825472U, 187957184U, 188087104U,
|
||||
188218304U, 188349376U, 188481344U, 188609728U, 188743616U, 188874304U,
|
||||
189005248U, 189136448U, 189265088U, 189396544U, 189528128U, 189660992U,
|
||||
189791936U, 189923264U, 190054208U, 190182848U, 190315072U, 190447424U,
|
||||
190577984U, 190709312U, 190840768U, 190971328U, 191102656U, 191233472U,
|
||||
191364032U, 191495872U, 191626816U, 191758016U, 191888192U, 192020288U,
|
||||
192148928U, 192282176U, 192413504U, 192542528U, 192674752U, 192805952U,
|
||||
192937792U, 193068608U, 193198912U, 193330496U, 193462208U, 193592384U,
|
||||
193723456U, 193854272U, 193985984U, 194116672U, 194247232U, 194379712U,
|
||||
194508352U, 194641856U, 194772544U, 194900672U, 195035072U, 195166016U,
|
||||
195296704U, 195428032U, 195558592U, 195690304U, 195818176U, 195952576U,
|
||||
196083392U, 196214336U, 196345792U, 196476736U, 196607552U, 196739008U,
|
||||
196869952U, 197000768U, 197130688U, 197262784U, 197394368U, 197523904U,
|
||||
197656384U, 197787584U, 197916608U, 198049472U, 198180544U, 198310208U,
|
||||
198442432U, 198573632U, 198705088U, 198834368U, 198967232U, 199097792U,
|
||||
199228352U, 199360192U, 199491392U, 199621696U, 199751744U, 199883968U,
|
||||
200014016U, 200146624U, 200276672U, 200408128U, 200540096U, 200671168U,
|
||||
200801984U, 200933312U, 201062464U, 201194944U, 201326144U, 201457472U,
|
||||
201588544U, 201719744U, 201850816U, 201981632U, 202111552U, 202244032U,
|
||||
202374464U, 202505152U, 202636352U, 202767808U, 202898368U, 203030336U,
|
||||
203159872U, 203292608U, 203423296U, 203553472U, 203685824U, 203816896U,
|
||||
203947712U, 204078272U, 204208192U, 204341056U, 204472256U, 204603328U,
|
||||
204733888U, 204864448U, 204996544U, 205125568U, 205258304U, 205388864U,
|
||||
205517632U, 205650112U, 205782208U, 205913536U, 206044736U, 206176192U,
|
||||
206307008U, 206434496U, 206569024U, 206700224U, 206831168U, 206961856U,
|
||||
207093056U, 207223616U, 207355328U, 207486784U, 207616832U, 207749056U,
|
||||
207879104U, 208010048U, 208141888U, 208273216U, 208404032U, 208534336U,
|
||||
208666048U, 208796864U, 208927424U, 209059264U, 209189824U, 209321792U,
|
||||
209451584U, 209582656U, 209715136U, 209845568U, 209976896U, 210106432U,
|
||||
210239296U, 210370112U, 210501568U, 210630976U, 210763712U, 210894272U,
|
||||
211024832U, 211156672U, 211287616U, 211418176U, 211549376U, 211679296U,
|
||||
211812032U, 211942592U, 212074432U, 212204864U, 212334016U, 212467648U,
|
||||
212597824U, 212727616U, 212860352U, 212991424U, 213120832U, 213253952U,
|
||||
213385024U, 213515584U, 213645632U, 213777728U, 213909184U, 214040128U,
|
||||
214170688U, 214302656U, 214433728U, 214564544U, 214695232U, 214826048U,
|
||||
214956992U, 215089088U, 215219776U, 215350592U, 215482304U, 215613248U,
|
||||
215743552U, 215874752U, 216005312U, 216137024U, 216267328U, 216399296U,
|
||||
216530752U, 216661696U, 216790592U, 216923968U, 217054528U, 217183168U,
|
||||
217316672U, 217448128U, 217579072U, 217709504U, 217838912U, 217972672U,
|
||||
218102848U, 218233024U, 218364736U, 218496832U, 218627776U, 218759104U,
|
||||
218888896U, 219021248U, 219151936U, 219281728U, 219413056U, 219545024U,
|
||||
219675968U, 219807296U, 219938624U, 220069312U, 220200128U, 220331456U,
|
||||
220461632U, 220592704U, 220725184U, 220855744U, 220987072U, 221117888U,
|
||||
221249216U, 221378368U, 221510336U, 221642048U, 221772736U, 221904832U,
|
||||
222031808U, 222166976U, 222297536U, 222428992U, 222559936U, 222690368U,
|
||||
222820672U, 222953152U, 223083968U, 223213376U, 223345984U, 223476928U,
|
||||
223608512U, 223738688U, 223869376U, 224001472U, 224132672U, 224262848U,
|
||||
224394944U, 224524864U, 224657344U, 224788288U, 224919488U, 225050432U,
|
||||
225181504U, 225312704U, 225443776U, 225574592U, 225704768U, 225834176U,
|
||||
225966784U, 226097216U, 226229824U, 226360384U, 226491712U, 226623424U,
|
||||
226754368U, 226885312U, 227015104U, 227147456U, 227278528U, 227409472U,
|
||||
227539904U, 227669696U, 227802944U, 227932352U, 228065216U, 228196288U,
|
||||
228326464U, 228457792U, 228588736U, 228720064U, 228850112U, 228981056U,
|
||||
229113152U, 229243328U, 229375936U, 229505344U, 229636928U, 229769152U,
|
||||
229894976U, 230030272U, 230162368U, 230292416U, 230424512U, 230553152U,
|
||||
230684864U, 230816704U, 230948416U, 231079616U, 231210944U, 231342016U,
|
||||
231472448U, 231603776U, 231733952U, 231866176U, 231996736U, 232127296U,
|
||||
232259392U, 232388672U, 232521664U, 232652608U, 232782272U, 232914496U,
|
||||
233043904U, 233175616U, 233306816U, 233438528U, 233569984U, 233699776U,
|
||||
233830592U, 233962688U, 234092224U, 234221888U, 234353984U, 234485312U,
|
||||
234618304U, 234749888U, 234880832U, 235011776U, 235142464U, 235274048U,
|
||||
235403456U, 235535936U, 235667392U, 235797568U, 235928768U, 236057152U,
|
||||
236190272U, 236322752U, 236453312U, 236583616U, 236715712U, 236846528U,
|
||||
236976448U, 237108544U, 237239104U, 237371072U, 237501632U, 237630784U,
|
||||
237764416U, 237895232U, 238026688U, 238157632U, 238286912U, 238419392U,
|
||||
238548032U, 238681024U, 238812608U, 238941632U, 239075008U, 239206336U,
|
||||
239335232U, 239466944U, 239599168U, 239730496U, 239861312U, 239992384U,
|
||||
240122816U, 240254656U, 240385856U, 240516928U, 240647872U, 240779072U,
|
||||
240909632U, 241040704U, 241171904U, 241302848U, 241433408U, 241565248U,
|
||||
241696192U, 241825984U, 241958848U, 242088256U, 242220224U, 242352064U,
|
||||
242481856U, 242611648U, 242744896U, 242876224U, 243005632U, 243138496U,
|
||||
243268672U, 243400384U, 243531712U, 243662656U, 243793856U, 243924544U,
|
||||
244054592U, 244187072U, 244316608U, 244448704U, 244580032U, 244710976U,
|
||||
244841536U, 244972864U, 245104448U, 245233984U, 245365312U, 245497792U,
|
||||
245628736U, 245759936U, 245889856U, 246021056U, 246152512U, 246284224U,
|
||||
246415168U, 246545344U, 246675904U, 246808384U, 246939584U, 247070144U,
|
||||
247199552U, 247331648U, 247463872U, 247593536U, 247726016U, 247857088U,
|
||||
247987648U, 248116928U, 248249536U, 248380736U, 248512064U, 248643008U,
|
||||
248773312U, 248901056U, 249036608U, 249167552U, 249298624U, 249429184U,
|
||||
249560512U, 249692096U, 249822784U, 249954112U, 250085312U, 250215488U,
|
||||
250345792U, 250478528U, 250608704U, 250739264U, 250870976U, 251002816U,
|
||||
251133632U, 251263552U, 251395136U, 251523904U, 251657792U, 251789248U,
|
||||
251919424U, 252051392U, 252182464U, 252313408U, 252444224U, 252575552U,
|
||||
252706624U, 252836032U, 252968512U, 253099712U, 253227584U, 253361728U,
|
||||
253493056U, 253623488U, 253754432U, 253885504U, 254017216U, 254148032U,
|
||||
254279488U, 254410432U, 254541376U, 254672576U, 254803264U, 254933824U,
|
||||
255065792U, 255196736U, 255326528U, 255458752U, 255589952U, 255721408U,
|
||||
255851072U, 255983296U, 256114624U, 256244416U, 256374208U, 256507712U,
|
||||
256636096U, 256768832U, 256900544U, 257031616U, 257162176U, 257294272U,
|
||||
257424448U, 257555776U, 257686976U, 257818432U, 257949632U, 258079552U,
|
||||
258211136U, 258342464U, 258473408U, 258603712U, 258734656U, 258867008U,
|
||||
258996544U, 259127744U, 259260224U, 259391296U, 259522112U, 259651904U,
|
||||
259784384U, 259915328U, 260045888U, 260175424U, 260308544U, 260438336U,
|
||||
260570944U, 260700992U, 260832448U, 260963776U, 261092672U, 261226304U,
|
||||
261356864U, 261487936U, 261619648U, 261750592U, 261879872U, 262011968U,
|
||||
262143424U, 262274752U, 262404416U, 262537024U, 262667968U, 262799296U,
|
||||
262928704U, 263061184U, 263191744U, 263322944U, 263454656U, 263585216U,
|
||||
263716672U, 263847872U, 263978944U, 264108608U, 264241088U, 264371648U,
|
||||
264501184U, 264632768U, 264764096U, 264895936U, 265024576U, 265158464U,
|
||||
265287488U, 265418432U, 265550528U, 265681216U, 265813312U, 265943488U,
|
||||
266075968U, 266206144U, 266337728U, 266468032U, 266600384U, 266731072U,
|
||||
266862272U, 266993344U, 267124288U, 267255616U, 267386432U, 267516992U,
|
||||
267648704U, 267777728U, 267910592U, 268040512U, 268172096U, 268302784U,
|
||||
268435264U, 268566208U, 268696256U, 268828096U, 268959296U, 269090368U,
|
||||
269221312U, 269352256U, 269482688U, 269614784U, 269745856U, 269876416U,
|
||||
270007616U, 270139328U, 270270272U, 270401216U, 270531904U, 270663616U,
|
||||
270791744U, 270924736U, 271056832U, 271186112U, 271317184U, 271449536U,
|
||||
271580992U, 271711936U, 271843136U, 271973056U, 272105408U, 272236352U,
|
||||
272367296U, 272498368U, 272629568U, 272759488U, 272891456U, 273022784U,
|
||||
273153856U, 273284672U, 273415616U, 273547072U, 273677632U, 273808448U,
|
||||
273937088U, 274071488U, 274200896U, 274332992U, 274463296U, 274595392U,
|
||||
274726208U, 274857536U, 274988992U, 275118656U, 275250496U, 275382208U,
|
||||
275513024U, 275643968U, 275775296U, 275906368U, 276037184U, 276167872U,
|
||||
276297664U, 276429376U, 276560576U, 276692672U, 276822976U, 276955072U,
|
||||
277085632U, 277216832U, 277347008U, 277478848U, 277609664U, 277740992U,
|
||||
277868608U, 278002624U, 278134336U, 278265536U, 278395328U, 278526784U,
|
||||
278657728U, 278789824U, 278921152U, 279052096U, 279182912U, 279313088U,
|
||||
279443776U, 279576256U, 279706048U, 279838528U, 279969728U, 280099648U,
|
||||
280230976U, 280361408U, 280493632U, 280622528U, 280755392U, 280887104U,
|
||||
281018176U, 281147968U, 281278912U, 281411392U, 281542592U, 281673152U,
|
||||
281803712U, 281935552U, 282066496U, 282197312U, 282329024U, 282458816U,
|
||||
282590272U, 282720832U, 282853184U, 282983744U, 283115072U, 283246144U,
|
||||
283377344U, 283508416U, 283639744U, 283770304U, 283901504U, 284032576U,
|
||||
284163136U, 284294848U, 284426176U, 284556992U, 284687296U, 284819264U,
|
||||
284950208U, 285081536U
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
76
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/ethash.h
generated
vendored
76
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/ethash.h
generated
vendored
|
|
@ -1,18 +1,18 @@
|
|||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of ethash.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
ethash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
ethash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with ethash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file ethash.h
|
||||
|
|
@ -26,13 +26,15 @@
|
|||
#include <stddef.h>
|
||||
#include "compiler.h"
|
||||
|
||||
#define REVISION 20
|
||||
#define DAGSIZE_BYTES_INIT 1073741824U // 2**30
|
||||
#define DAG_GROWTH 8388608U // 2**23
|
||||
#define CACHE_MULTIPLIER 1024
|
||||
#define REVISION 23
|
||||
#define DATASET_BYTES_INIT 1073741824U // 2**30
|
||||
#define DATASET_BYTES_GROWTH 8388608U // 2**23
|
||||
#define CACHE_BYTES_INIT 1073741824U // 2**24
|
||||
#define CACHE_BYTES_GROWTH 131072U // 2**17
|
||||
#define EPOCH_LENGTH 30000U
|
||||
#define MIX_BYTES 128
|
||||
#define DAG_PARENTS 256
|
||||
#define HASH_BYTES 64
|
||||
#define DATASET_PARENTS 256
|
||||
#define CACHE_ROUNDS 3
|
||||
#define ACCESSES 64
|
||||
|
||||
|
|
@ -41,8 +43,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef struct ethash_params {
|
||||
size_t full_size; // Size of full data set (in bytes, multiple of mix size (128)).
|
||||
size_t cache_size; // Size of compute cache (in bytes, multiple of node size (64)).
|
||||
uint64_t full_size; // Size of full data set (in bytes, multiple of mix size (128)).
|
||||
uint64_t cache_size; // Size of compute cache (in bytes, multiple of node size (64)).
|
||||
} ethash_params;
|
||||
|
||||
typedef struct ethash_return_value {
|
||||
|
|
@ -50,29 +52,55 @@ typedef struct ethash_return_value {
|
|||
uint8_t mix_hash[32];
|
||||
} ethash_return_value;
|
||||
|
||||
size_t ethash_get_datasize(const uint32_t block_number);
|
||||
size_t ethash_get_cachesize(const uint32_t block_number);
|
||||
uint64_t ethash_get_datasize(const uint32_t block_number);
|
||||
uint64_t ethash_get_cachesize(const uint32_t block_number);
|
||||
|
||||
// initialize the parameters
|
||||
static inline void ethash_params_init(ethash_params *params, const uint32_t block_number) {
|
||||
// Initialize the Parameters
|
||||
static inline int ethash_params_init(ethash_params *params, const uint32_t block_number) {
|
||||
params->full_size = ethash_get_datasize(block_number);
|
||||
if (params->full_size == 0)
|
||||
return 0;
|
||||
|
||||
params->cache_size = ethash_get_cachesize(block_number);
|
||||
if (params->cache_size == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct ethash_cache {
|
||||
void *mem;
|
||||
} ethash_cache;
|
||||
|
||||
void ethash_mkcache(ethash_cache *cache, ethash_params const *params, const uint8_t seed[32]);
|
||||
void ethash_compute_full_data(void *mem, ethash_params const *params, ethash_cache const *cache);
|
||||
void ethash_full(ethash_return_value *ret, void const *full_mem, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce);
|
||||
void ethash_light(ethash_return_value *ret, ethash_cache const *cache, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce);
|
||||
int ethash_mkcache(ethash_cache *cache, ethash_params const *params, const uint8_t seed[32]);
|
||||
int ethash_compute_full_data(void *mem, ethash_params const *params, ethash_cache const *cache);
|
||||
int ethash_full(ethash_return_value *ret, void const *full_mem, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce);
|
||||
int ethash_light(ethash_return_value *ret, ethash_cache const *cache, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce);
|
||||
void ethash_get_seedhash(uint8_t seedhash[32], const uint32_t block_number);
|
||||
|
||||
static inline void ethash_prep_light(void *cache, ethash_params const *params, const uint8_t seed[32]) { ethash_cache c; c.mem = cache; ethash_mkcache(&c, params, seed); }
|
||||
static inline void ethash_compute_light(ethash_return_value *ret, void const *cache, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce) { ethash_cache c; c.mem = (void*)cache; ethash_light(ret, &c, params, header_hash, nonce); }
|
||||
static inline void ethash_prep_full(void *full, ethash_params const *params, void const *cache) { ethash_cache c; c.mem = (void*)cache; ethash_compute_full_data(full, params, &c); }
|
||||
static inline void ethash_compute_full(ethash_return_value *ret, void const *full, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce) { ethash_full(ret, full, params, header_hash, nonce); }
|
||||
static inline int ethash_prep_light(void *cache, ethash_params const *params, const uint8_t seed[32]) {
|
||||
ethash_cache c;
|
||||
c.mem = cache;
|
||||
return ethash_mkcache(&c, params, seed);
|
||||
}
|
||||
|
||||
static inline int ethash_compute_light(ethash_return_value *ret, void const *cache, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce) {
|
||||
ethash_cache c;
|
||||
c.mem = (void *) cache;
|
||||
return ethash_light(ret, &c, params, header_hash, nonce);
|
||||
}
|
||||
|
||||
static inline int ethash_prep_full(void *full, ethash_params const *params, void const *cache) {
|
||||
ethash_cache c;
|
||||
c.mem = (void *) cache;
|
||||
return ethash_compute_full_data(full, params, &c);
|
||||
}
|
||||
|
||||
static inline int ethash_compute_full(ethash_return_value *ret, void const *full, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce) {
|
||||
return ethash_full(ret, full, params, header_hash, nonce);
|
||||
}
|
||||
|
||||
// Returns if hash is less than or equal to difficulty
|
||||
static inline int ethash_check_difficulty(
|
||||
const uint8_t hash[32],
|
||||
const uint8_t difficulty[32]) {
|
||||
|
|
@ -81,7 +109,7 @@ static inline int ethash_check_difficulty(
|
|||
if (hash[i] == difficulty[i]) continue;
|
||||
return hash[i] < difficulty[i];
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ethash_quick_check_difficulty(
|
||||
|
|
|
|||
162
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.c
generated
vendored
162
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.c
generated
vendored
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of ethash.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
ethash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
ethash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
|
@ -14,13 +14,12 @@
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file dash.cpp
|
||||
/** @file internal.c
|
||||
* @author Tim Hughes <tim@twistedfury.com>
|
||||
* @author Matthew Wampler-Doty
|
||||
* @date 2015
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include "ethash.h"
|
||||
|
|
@ -29,6 +28,9 @@
|
|||
#include "internal.h"
|
||||
#include "data_sizes.h"
|
||||
|
||||
// Inline assembly doesn't work
|
||||
#define ENABLE_SSE 0
|
||||
|
||||
#ifdef WITH_CRYPTOPP
|
||||
|
||||
#include "sha3_cryptopp.h"
|
||||
|
|
@ -37,25 +39,30 @@
|
|||
#include "sha3.h"
|
||||
#endif // WITH_CRYPTOPP
|
||||
|
||||
size_t ethash_get_datasize(const uint32_t block_number) {
|
||||
assert(block_number / EPOCH_LENGTH < 500);
|
||||
uint64_t ethash_get_datasize(const uint32_t block_number) {
|
||||
if (block_number / EPOCH_LENGTH >= 2048)
|
||||
return 0;
|
||||
return dag_sizes[block_number / EPOCH_LENGTH];
|
||||
}
|
||||
|
||||
size_t ethash_get_cachesize(const uint32_t block_number) {
|
||||
assert(block_number / EPOCH_LENGTH < 500);
|
||||
uint64_t ethash_get_cachesize(const uint32_t block_number) {
|
||||
if (block_number / EPOCH_LENGTH >= 2048)
|
||||
return 0;
|
||||
return cache_sizes[block_number / EPOCH_LENGTH];
|
||||
}
|
||||
|
||||
// Follows Sergio's "STRICT MEMORY HARD HASHING FUNCTIONS" (2014)
|
||||
// https://bitslog.files.wordpress.com/2013/12/memohash-v0-3.pdf
|
||||
// SeqMemoHash(s, R, N)
|
||||
void static ethash_compute_cache_nodes(
|
||||
int static ethash_compute_cache_nodes(
|
||||
node *const nodes,
|
||||
ethash_params const *params,
|
||||
const uint8_t seed[32]) {
|
||||
assert((params->cache_size % sizeof(node)) == 0);
|
||||
uint32_t const num_nodes = (uint32_t)(params->cache_size / sizeof(node));
|
||||
|
||||
if ((params->cache_size % sizeof(node)) != 0)
|
||||
return 0;
|
||||
|
||||
uint32_t const num_nodes = (uint32_t) (params->cache_size / sizeof(node));
|
||||
|
||||
SHA3_512(nodes[0].bytes, seed, 32);
|
||||
|
||||
|
|
@ -68,8 +75,7 @@ void static ethash_compute_cache_nodes(
|
|||
uint32_t const idx = nodes[i].words[0] % num_nodes;
|
||||
node data;
|
||||
data = nodes[(num_nodes - 1 + i) % num_nodes];
|
||||
for (unsigned w = 0; w != NODE_WORDS; ++w)
|
||||
{
|
||||
for (unsigned w = 0; w != NODE_WORDS; ++w) {
|
||||
data.words[w] ^= nodes[idx].words[w];
|
||||
}
|
||||
SHA3_512(nodes[i].bytes, data.bytes, sizeof(data));
|
||||
|
|
@ -83,23 +89,28 @@ void static ethash_compute_cache_nodes(
|
|||
nodes->words[w] = fix_endian32(nodes->words[w]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ethash_mkcache(
|
||||
int ethash_mkcache(
|
||||
ethash_cache *cache,
|
||||
ethash_params const *params,
|
||||
const uint8_t seed[32]) {
|
||||
node *nodes = (node *) cache->mem;
|
||||
ethash_compute_cache_nodes(nodes, params, seed);
|
||||
return ethash_compute_cache_nodes(nodes, params, seed);
|
||||
}
|
||||
|
||||
void ethash_calculate_dag_item(
|
||||
int ethash_calculate_dag_item(
|
||||
node *const ret,
|
||||
const unsigned node_index,
|
||||
const uint64_t node_index,
|
||||
const struct ethash_params *params,
|
||||
const struct ethash_cache *cache) {
|
||||
|
||||
uint32_t num_parent_nodes = (uint32_t)(params->cache_size / sizeof(node));
|
||||
if (params->cache_size % sizeof(node) != 0)
|
||||
return 0;
|
||||
|
||||
uint32_t num_parent_nodes = (uint32_t) (params->cache_size / sizeof(node));
|
||||
node const *cache_nodes = (node const *) cache->mem;
|
||||
node const *init = &cache_nodes[node_index % num_parent_nodes];
|
||||
|
||||
|
|
@ -115,12 +126,11 @@ void ethash_calculate_dag_item(
|
|||
__m128i xmm3 = ret->xmm[3];
|
||||
#endif
|
||||
|
||||
for (unsigned i = 0; i != DAG_PARENTS; ++i)
|
||||
{
|
||||
uint32_t parent_index = ((node_index ^ i)*FNV_PRIME ^ ret->words[i % NODE_WORDS]) % num_parent_nodes;
|
||||
for (unsigned i = 0; i != DATASET_PARENTS; ++i) {
|
||||
uint32_t parent_index = ((node_index ^ i) * FNV_PRIME ^ ret->words[i % NODE_WORDS]) % num_parent_nodes;
|
||||
node const *parent = &cache_nodes[parent_index];
|
||||
|
||||
#if defined(_M_X64) && ENABLE_SSE
|
||||
#if defined(_M_X64) && ENABLE_SSE
|
||||
{
|
||||
xmm0 = _mm_mullo_epi32(xmm0, fnv_prime);
|
||||
xmm1 = _mm_mullo_epi32(xmm1, fnv_prime);
|
||||
|
|
@ -143,38 +153,73 @@ void ethash_calculate_dag_item(
|
|||
ret->words[w] = fnv_hash(ret->words[w], parent->words[w]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
SHA3_512(ret->bytes, ret->bytes, sizeof(node));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ethash_compute_full_data(
|
||||
int ethash_compute_full_data(
|
||||
void *mem,
|
||||
ethash_params const *params,
|
||||
ethash_cache const *cache) {
|
||||
assert((params->full_size % (sizeof(uint32_t) * MIX_WORDS)) == 0);
|
||||
assert((params->full_size % sizeof(node)) == 0);
|
||||
|
||||
if ((params->full_size % (sizeof(uint32_t) * MIX_WORDS)) != 0)
|
||||
return 0;
|
||||
|
||||
if ((params->full_size % sizeof(node)) != 0)
|
||||
return 0;
|
||||
|
||||
node *full_nodes = mem;
|
||||
|
||||
// now compute full nodes
|
||||
for (unsigned n = 0; n != (params->full_size / sizeof(node)); ++n) {
|
||||
for (uint64_t n = 0; n != (params->full_size / sizeof(node)); ++n) {
|
||||
ethash_calculate_dag_item(&(full_nodes[n]), n, params, cache);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ethash_hash(
|
||||
ethash_return_value * ret,
|
||||
int ethash_compute_full_data_section(
|
||||
void *mem,
|
||||
ethash_params const *params,
|
||||
ethash_cache const *cache,
|
||||
uint64_t const start,
|
||||
uint64_t const end) {
|
||||
|
||||
if ((params->full_size % (sizeof(uint32_t) * MIX_WORDS)) != 0)
|
||||
return 0;
|
||||
|
||||
if ((params->full_size % sizeof(node)) != 0)
|
||||
return 0;
|
||||
|
||||
if (end >= params->full_size)
|
||||
return 0;
|
||||
|
||||
if (start >= end)
|
||||
return 0;
|
||||
|
||||
node *full_nodes = mem;
|
||||
|
||||
// now compute full nodes
|
||||
for (uint64_t n = start; n != end; ++n) {
|
||||
ethash_calculate_dag_item(&(full_nodes[n]), n, params, cache);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ethash_hash(
|
||||
ethash_return_value *ret,
|
||||
node const *full_nodes,
|
||||
ethash_cache const *cache,
|
||||
ethash_params const *params,
|
||||
const uint8_t header_hash[32],
|
||||
const uint64_t nonce) {
|
||||
|
||||
assert((params->full_size % MIX_WORDS) == 0);
|
||||
if ((params->full_size % MIX_WORDS) != 0)
|
||||
return 0;
|
||||
|
||||
// pack hash and nonce together into first 40 bytes of s_mix
|
||||
assert(sizeof(node)*8 == 512);
|
||||
node s_mix[MIX_NODES + 1];
|
||||
memcpy(s_mix[0].bytes, header_hash, 32);
|
||||
|
||||
|
|
@ -193,23 +238,21 @@ static void ethash_hash(
|
|||
}
|
||||
#endif
|
||||
|
||||
node* const mix = s_mix + 1;
|
||||
node *const mix = s_mix + 1;
|
||||
for (unsigned w = 0; w != MIX_WORDS; ++w) {
|
||||
mix->words[w] = s_mix[0].words[w % NODE_WORDS];
|
||||
}
|
||||
|
||||
unsigned const
|
||||
page_size = sizeof(uint32_t) * MIX_WORDS,
|
||||
num_full_pages = (unsigned)(params->full_size / page_size);
|
||||
num_full_pages = (unsigned) (params->full_size / page_size);
|
||||
|
||||
|
||||
for (unsigned i = 0; i != ACCESSES; ++i)
|
||||
{
|
||||
uint32_t const index = ((s_mix->words[0] ^ i)*FNV_PRIME ^ mix->words[i % MIX_WORDS]) % num_full_pages;
|
||||
for (unsigned i = 0; i != ACCESSES; ++i) {
|
||||
uint32_t const index = ((s_mix->words[0] ^ i) * FNV_PRIME ^ mix->words[i % MIX_WORDS]) % num_full_pages;
|
||||
|
||||
for (unsigned n = 0; n != MIX_NODES; ++n)
|
||||
{
|
||||
const node * dag_node = &full_nodes[MIX_NODES * index + n];
|
||||
for (unsigned n = 0; n != MIX_NODES; ++n) {
|
||||
const node *dag_node = &full_nodes[MIX_NODES * index + n];
|
||||
|
||||
if (!full_nodes) {
|
||||
node tmp_node;
|
||||
|
|
@ -217,7 +260,7 @@ static void ethash_hash(
|
|||
dag_node = &tmp_node;
|
||||
}
|
||||
|
||||
#if defined(_M_X64) && ENABLE_SSE
|
||||
#if defined(_M_X64) && ENABLE_SSE
|
||||
{
|
||||
__m128i fnv_prime = _mm_set1_epi32(FNV_PRIME);
|
||||
__m128i xmm0 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[0]);
|
||||
|
|
@ -235,19 +278,18 @@ static void ethash_hash(
|
|||
mix[n].words[w] = fnv_hash(mix[n].words[w], dag_node->words[w]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// compress mix
|
||||
for (unsigned w = 0; w != MIX_WORDS; w += 4)
|
||||
{
|
||||
uint32_t reduction = mix->words[w+0];
|
||||
reduction = reduction*FNV_PRIME ^ mix->words[w+1];
|
||||
reduction = reduction*FNV_PRIME ^ mix->words[w+2];
|
||||
reduction = reduction*FNV_PRIME ^ mix->words[w+3];
|
||||
mix->words[w/4] = reduction;
|
||||
for (unsigned w = 0; w != MIX_WORDS; w += 4) {
|
||||
uint32_t reduction = mix->words[w + 0];
|
||||
reduction = reduction * FNV_PRIME ^ mix->words[w + 1];
|
||||
reduction = reduction * FNV_PRIME ^ mix->words[w + 2];
|
||||
reduction = reduction * FNV_PRIME ^ mix->words[w + 3];
|
||||
mix->words[w / 4] = reduction;
|
||||
}
|
||||
|
||||
#if BYTE_ORDER != LITTLE_ENDIAN
|
||||
|
|
@ -258,7 +300,8 @@ static void ethash_hash(
|
|||
|
||||
memcpy(ret->mix_hash, mix->bytes, 32);
|
||||
// final Keccak hash
|
||||
SHA3_256(ret->result, s_mix->bytes, 64+32); // Keccak-256(s + compressed_mix)
|
||||
SHA3_256(ret->result, s_mix->bytes, 64 + 32); // Keccak-256(s + compressed_mix)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ethash_quick_hash(
|
||||
|
|
@ -267,7 +310,7 @@ void ethash_quick_hash(
|
|||
const uint64_t nonce,
|
||||
const uint8_t mix_hash[32]) {
|
||||
|
||||
uint8_t buf[64+32];
|
||||
uint8_t buf[64 + 32];
|
||||
memcpy(buf, header_hash, 32);
|
||||
#if BYTE_ORDER != LITTLE_ENDIAN
|
||||
nonce = fix_endian64(nonce);
|
||||
|
|
@ -275,7 +318,14 @@ void ethash_quick_hash(
|
|||
memcpy(&(buf[32]), &nonce, 8);
|
||||
SHA3_512(buf, buf, 40);
|
||||
memcpy(&(buf[64]), mix_hash, 32);
|
||||
SHA3_256(return_hash, buf, 64+32);
|
||||
SHA3_256(return_hash, buf, 64 + 32);
|
||||
}
|
||||
|
||||
void ethash_get_seedhash(uint8_t seedhash[32], const uint32_t block_number) {
|
||||
memset(seedhash, 0, 32);
|
||||
const uint32_t epochs = block_number / EPOCH_LENGTH;
|
||||
for (uint32_t i = 0; i < epochs; ++i)
|
||||
SHA3_256(seedhash, seedhash, 32);
|
||||
}
|
||||
|
||||
int ethash_quick_check_difficulty(
|
||||
|
|
@ -289,10 +339,10 @@ int ethash_quick_check_difficulty(
|
|||
return ethash_check_difficulty(return_hash, difficulty);
|
||||
}
|
||||
|
||||
void ethash_full(ethash_return_value * ret, void const *full_mem, ethash_params const *params, const uint8_t previous_hash[32], const uint64_t nonce) {
|
||||
ethash_hash(ret, (node const *) full_mem, NULL, params, previous_hash, nonce);
|
||||
int ethash_full(ethash_return_value *ret, void const *full_mem, ethash_params const *params, const uint8_t previous_hash[32], const uint64_t nonce) {
|
||||
return ethash_hash(ret, (node const *) full_mem, NULL, params, previous_hash, nonce);
|
||||
}
|
||||
|
||||
void ethash_light(ethash_return_value * ret, ethash_cache const *cache, ethash_params const *params, const uint8_t previous_hash[32], const uint64_t nonce) {
|
||||
ethash_hash(ret, NULL, cache, params, previous_hash, nonce);
|
||||
int ethash_light(ethash_return_value *ret, ethash_cache const *cache, ethash_params const *params, const uint8_t previous_hash[32], const uint64_t nonce) {
|
||||
return ethash_hash(ret, NULL, cache, params, previous_hash, nonce);
|
||||
}
|
||||
6
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.h
generated
vendored
6
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/internal.h
generated
vendored
|
|
@ -3,7 +3,7 @@
|
|||
#include "endian.h"
|
||||
#include "ethash.h"
|
||||
|
||||
#define ENABLE_SSE 1
|
||||
#define ENABLE_SSE 0
|
||||
|
||||
#if defined(_M_X64) && ENABLE_SSE
|
||||
#include <smmintrin.h>
|
||||
|
|
@ -30,9 +30,9 @@ typedef union node {
|
|||
|
||||
} node;
|
||||
|
||||
void ethash_calculate_dag_item(
|
||||
int ethash_calculate_dag_item(
|
||||
node *const ret,
|
||||
const unsigned node_index,
|
||||
const uint64_t node_index,
|
||||
ethash_params const *params,
|
||||
ethash_cache const *cache
|
||||
);
|
||||
|
|
|
|||
8
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.cpp
generated
vendored
8
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.cpp
generated
vendored
|
|
@ -1,18 +1,18 @@
|
|||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of ethash.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
ethash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
ethash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with ethash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file sha3.cpp
|
||||
|
|
|
|||
8
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util.h
generated
vendored
8
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/util.h
generated
vendored
|
|
@ -1,18 +1,18 @@
|
|||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of ethash.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
ethash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
ethash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with ethash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file util.h
|
||||
* @author Tim Hughes <tim@twistedfury.com>
|
||||
|
|
|
|||
295
Godeps/_workspace/src/github.com/ethereum/ethash/src/python/core.c
generated
vendored
295
Godeps/_workspace/src/github.com/ethereum/ethash/src/python/core.c
generated
vendored
|
|
@ -1,64 +1,305 @@
|
|||
#include <Python.h>
|
||||
#include <alloca.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "../libethash/ethash.h"
|
||||
|
||||
static PyObject*
|
||||
get_cache_size(PyObject* self, PyObject* args)
|
||||
{
|
||||
#define MIX_WORDS (MIX_BYTES/4)
|
||||
|
||||
static PyObject *
|
||||
get_cache_size(PyObject *self, PyObject *args) {
|
||||
unsigned long block_number;
|
||||
if (!PyArg_ParseTuple(args, "k", &block_number))
|
||||
return 0;
|
||||
if (block_number >= EPOCH_LENGTH * 2048) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "Block number must be less than %i (was %lu)", EPOCH_LENGTH * 2048, block_number);
|
||||
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Py_BuildValue("i", ethash_get_cachesize(block_number));
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
get_full_size(PyObject* self, PyObject* args)
|
||||
{
|
||||
static PyObject *
|
||||
get_full_size(PyObject *self, PyObject *args) {
|
||||
unsigned long block_number;
|
||||
if (!PyArg_ParseTuple(args, "k", &block_number))
|
||||
return 0;
|
||||
if (block_number >= EPOCH_LENGTH * 2048) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "Block number must be less than %i (was %lu)", EPOCH_LENGTH * 2048, block_number);
|
||||
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Py_BuildValue("i", ethash_get_datasize(block_number));
|
||||
}
|
||||
|
||||
|
||||
static PyObject*
|
||||
mkcache(PyObject* self, PyObject* args)
|
||||
{
|
||||
char * seed;
|
||||
static PyObject *
|
||||
mkcache_bytes(PyObject *self, PyObject *args) {
|
||||
char *seed;
|
||||
unsigned long cache_size;
|
||||
int seed_len;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ks#", &cache_size, &seed, &seed_len))
|
||||
return 0;
|
||||
|
||||
if (seed_len != 32)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Seed must be 32 bytes long");
|
||||
if (seed_len != 32) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "Seed must be 32 bytes long (was %i)", seed_len);
|
||||
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("cache size: %lu\n", cache_size);
|
||||
ethash_params params;
|
||||
params.cache_size = (size_t) cache_size;
|
||||
params.cache_size = (uint64_t) cache_size;
|
||||
ethash_cache cache;
|
||||
cache.mem = alloca(cache_size);
|
||||
cache.mem = malloc(cache_size);
|
||||
ethash_mkcache(&cache, ¶ms, (uint8_t *) seed);
|
||||
return PyString_FromStringAndSize(cache.mem, cache_size);
|
||||
PyObject * val = Py_BuildValue("s#", cache.mem, cache_size);
|
||||
free(cache.mem);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef CoreMethods[] =
|
||||
{
|
||||
{"get_cache_size", get_cache_size, METH_VARARGS, "Get the cache size for a given block number"},
|
||||
{"get_full_size", get_full_size, METH_VARARGS, "Get the full size for a given block number"},
|
||||
{"mkcache", mkcache, METH_VARARGS, "Makes the cache for given parameters and seed hash"},
|
||||
static PyObject *
|
||||
calc_dataset_bytes(PyObject *self, PyObject *args) {
|
||||
char *cache_bytes;
|
||||
unsigned long full_size;
|
||||
int cache_size;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ks#", &full_size, &cache_bytes, &cache_size))
|
||||
return 0;
|
||||
|
||||
if (full_size % MIX_WORDS != 0) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "The size of data set must be a multiple of %i bytes (was %lu)", MIX_WORDS, full_size);
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cache_size % HASH_BYTES != 0) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "The size of the cache must be a multiple of %i bytes (was %i)", HASH_BYTES, cache_size);
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ethash_params params;
|
||||
params.cache_size = (uint64_t) cache_size;
|
||||
params.full_size = (uint64_t) full_size;
|
||||
ethash_cache cache;
|
||||
cache.mem = (void *) cache_bytes;
|
||||
void *mem = malloc(params.full_size);
|
||||
ethash_compute_full_data(mem, ¶ms, &cache);
|
||||
PyObject * val = Py_BuildValue("s#", (char *) mem, full_size);
|
||||
free(mem);
|
||||
return val;
|
||||
}
|
||||
|
||||
// hashimoto_light(full_size, cache, header, nonce)
|
||||
static PyObject *
|
||||
hashimoto_light(PyObject *self, PyObject *args) {
|
||||
char *cache_bytes, *header;
|
||||
unsigned long full_size;
|
||||
unsigned long long nonce;
|
||||
int cache_size, header_size;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ks#s#K", &full_size, &cache_bytes, &cache_size, &header, &header_size, &nonce))
|
||||
return 0;
|
||||
|
||||
if (full_size % MIX_WORDS != 0) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "The size of data set must be a multiple of %i bytes (was %lu)", MIX_WORDS, full_size);
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cache_size % HASH_BYTES != 0) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "The size of the cache must be a multiple of %i bytes (was %i)", HASH_BYTES, cache_size);
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (header_size != 32) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "Seed must be 32 bytes long (was %i)", header_size);
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ethash_return_value out;
|
||||
ethash_params params;
|
||||
params.cache_size = (uint64_t) cache_size;
|
||||
params.full_size = (uint64_t) full_size;
|
||||
ethash_cache cache;
|
||||
cache.mem = (void *) cache_bytes;
|
||||
ethash_light(&out, &cache, ¶ms, (uint8_t *) header, nonce);
|
||||
return Py_BuildValue("{s:s#,s:s#}",
|
||||
"mix digest", out.mix_hash, 32,
|
||||
"result", out.result, 32);
|
||||
}
|
||||
|
||||
// hashimoto_full(dataset, header, nonce)
|
||||
static PyObject *
|
||||
hashimoto_full(PyObject *self, PyObject *args) {
|
||||
char *full_bytes, *header;
|
||||
unsigned long long nonce;
|
||||
int full_size, header_size;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s#s#K", &full_bytes, &full_size, &header, &header_size, &nonce))
|
||||
return 0;
|
||||
|
||||
if (full_size % MIX_WORDS != 0) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "The size of data set must be a multiple of %i bytes (was %i)", MIX_WORDS, full_size);
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (header_size != 32) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "Header must be 32 bytes long (was %i)", header_size);
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ethash_return_value out;
|
||||
ethash_params params;
|
||||
params.full_size = (uint64_t) full_size;
|
||||
ethash_full(&out, (void *) full_bytes, ¶ms, (uint8_t *) header, nonce);
|
||||
return Py_BuildValue("{s:s#, s:s#}",
|
||||
"mix digest", out.mix_hash, 32,
|
||||
"result", out.result, 32);
|
||||
}
|
||||
|
||||
// mine(dataset_bytes, header, difficulty_bytes)
|
||||
static PyObject *
|
||||
mine(PyObject *self, PyObject *args) {
|
||||
char *full_bytes, *header, *difficulty;
|
||||
srand(time(0));
|
||||
uint64_t nonce = ((uint64_t) rand()) << 32 | rand();
|
||||
int full_size, header_size, difficulty_size;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s#s#s#", &full_bytes, &full_size, &header, &header_size, &difficulty, &difficulty_size))
|
||||
return 0;
|
||||
|
||||
if (full_size % MIX_WORDS != 0) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "The size of data set must be a multiple of %i bytes (was %i)", MIX_WORDS, full_size);
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (header_size != 32) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "Header must be 32 bytes long (was %i)", header_size);
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (difficulty_size != 32) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "Difficulty must be an array of 32 bytes (only had %i)", difficulty_size);
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ethash_return_value out;
|
||||
ethash_params params;
|
||||
params.full_size = (uint64_t) full_size;
|
||||
|
||||
// TODO: Multi threading?
|
||||
do {
|
||||
ethash_full(&out, (void *) full_bytes, ¶ms, (const uint8_t *) header, nonce++);
|
||||
// TODO: disagrees with the spec https://github.com/ethereum/wiki/wiki/Ethash#mining
|
||||
} while (!ethash_check_difficulty(out.result, (const uint8_t *) difficulty));
|
||||
|
||||
return Py_BuildValue("{s:s#, s:s#, s:K}",
|
||||
"mix digest", out.mix_hash, 32,
|
||||
"result", out.result, 32,
|
||||
"nonce", nonce);
|
||||
}
|
||||
|
||||
//get_seedhash(block_number)
|
||||
static PyObject *
|
||||
get_seedhash(PyObject *self, PyObject *args) {
|
||||
unsigned long block_number;
|
||||
if (!PyArg_ParseTuple(args, "k", &block_number))
|
||||
return 0;
|
||||
if (block_number >= EPOCH_LENGTH * 2048) {
|
||||
char error_message[1024];
|
||||
sprintf(error_message, "Block number must be less than %i (was %lu)", EPOCH_LENGTH * 2048, block_number);
|
||||
|
||||
PyErr_SetString(PyExc_ValueError, error_message);
|
||||
return 0;
|
||||
}
|
||||
uint8_t seedhash[32];
|
||||
ethash_get_seedhash(seedhash, block_number);
|
||||
return Py_BuildValue("s#", (char *) seedhash, 32);
|
||||
}
|
||||
|
||||
static PyMethodDef PyethashMethods[] =
|
||||
{
|
||||
{"get_cache_size", get_cache_size, METH_VARARGS,
|
||||
"get_cache_size(block_number)\n\n"
|
||||
"Get the cache size for a given block number\n"
|
||||
"\nExample:\n"
|
||||
">>> get_cache_size(0)\n"
|
||||
"1048384"},
|
||||
{"get_full_size", get_full_size, METH_VARARGS,
|
||||
"get_full_size(block_number)\n\n"
|
||||
"Get the full size for a given block number\n"
|
||||
"\nExample:\n"
|
||||
">>> get_full_size(0)\n"
|
||||
"1073739904"
|
||||
},
|
||||
{"get_seedhash", get_seedhash, METH_VARARGS,
|
||||
"get_seedhash(block_number)\n\n"
|
||||
"Gets the seedhash for a block."},
|
||||
{"mkcache_bytes", mkcache_bytes, METH_VARARGS,
|
||||
"mkcache_bytes(size, header)\n\n"
|
||||
"Makes a byte array for the cache for given cache size and seed hash\n"
|
||||
"\nExample:\n"
|
||||
">>> pyethash.mkcache_bytes( 1024, \"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\").encode('hex')"
|
||||
"\"2da2b506f21070e1143d908e867962486d6b0a02e31d468fd5e3a7143aafa76a14201f63374314e2a6aaf84ad2eb57105dea3378378965a1b3873453bb2b78f9a8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995c259440b89fa3481c2c33171477c305c8e1e421f8d8f6d59585449d0034f3e421808d8da6bbd0b6378f567647cc6c4ba6c434592b198ad444e7284905b7c6adaf70bf43ec2daa7bd5e8951aa609ab472c124cf9eba3d38cff5091dc3f58409edcc386c743c3bd66f92408796ee1e82dd149eaefbf52b00ce33014a6eb3e50625413b072a58bc01da28262f42cbe4f87d4abc2bf287d15618405a1fe4e386fcdafbb171064bd99901d8f81dd6789396ce5e364ac944bbbd75a7827291c70b42d26385910cd53ca535ab29433dd5c5714d26e0dce95514c5ef866329c12e958097e84462197c2b32087849dab33e88b11da61d52f9dbc0b92cc61f742c07dbbf751c49d7678624ee60dfbe62e5e8c47a03d8247643f3d16ad8c8e663953bcda1f59d7e2d4a9bf0768e789432212621967a8f41121ad1df6ae1fa78782530695414c6213942865b2730375019105cae91a4c17a558d4b63059661d9f108362143107babe0b848de412e4da59168cce82bfbff3c99e022dd6ac1e559db991f2e3f7bb910cefd173e65ed00a8d5d416534e2c8416ff23977dbf3eb7180b75c71580d08ce95efeb9b0afe904ea12285a392aff0c8561ff79fca67f694a62b9e52377485c57cc3598d84cac0a9d27960de0cc31ff9bbfe455acaa62c8aa5d2cce96f345da9afe843d258a99c4eaf3650fc62efd81c7b81cd0d534d2d71eeda7a6e315d540b4473c80f8730037dc2ae3e47b986240cfc65ccc565f0d8cde0bc68a57e39a271dda57440b3598bee19f799611d25731a96b5dbbbefdff6f4f656161462633030d62560ea4e9c161cf78fc96a2ca5aaa32453a6c5dea206f766244e8c9d9a8dc61185ce37f1fc804459c5f07434f8ecb34141b8dcae7eae704c950b55556c5f40140c3714b45eddb02637513268778cbf937a33e4e33183685f9deb31ef54e90161e76d969587dd782eaa94e289420e7c2ee908517f5893a26fdb5873d68f92d118d4bcf98d7a4916794d6ab290045e30f9ea00ca547c584b8482b0331ba1539a0f2714fddc3a0b06b0cfbb6a607b8339c39bcfd6640b1f653e9d70ef6c985b\""},
|
||||
{"calc_dataset_bytes", calc_dataset_bytes, METH_VARARGS,
|
||||
"calc_dataset_bytes(full_size, cache_bytes)\n\n"
|
||||
"Makes a byte array for the dataset for a given size given cache bytes"},
|
||||
{"hashimoto_light", hashimoto_light, METH_VARARGS,
|
||||
"hashimoto_light(full_size, cache_bytes, header, nonce)\n\n"
|
||||
"Runs the hashimoto hashing function just using cache bytes. Takes an int (full_size), byte array (cache_bytes), another byte array (header), and an int (nonce). Returns an object containing the mix digest, and hash result."},
|
||||
{"hashimoto_full", hashimoto_full, METH_VARARGS,
|
||||
"hashimoto_full(dataset_bytes, header, nonce)\n\n"
|
||||
"Runs the hashimoto hashing function using the dataset bytes. Useful for testing. Returns an object containing the mix digest (byte array), and hash result (another byte array)."},
|
||||
{"mine", mine, METH_VARARGS,
|
||||
"mine(dataset_bytes, header, difficulty_bytes)\n\n"
|
||||
"Mine for an adequate header. Returns an object containing the mix digest (byte array), hash result (another byte array) and nonce (an int)."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
initcore(void)
|
||||
{
|
||||
(void) Py_InitModule("core", CoreMethods);
|
||||
initpyethash(void) {
|
||||
PyObject *module = Py_InitModule("pyethash", PyethashMethods);
|
||||
// Following Spec: https://github.com/ethereum/wiki/wiki/Ethash#definitions
|
||||
PyModule_AddIntConstant(module, "REVISION", (long) REVISION);
|
||||
PyModule_AddIntConstant(module, "DATASET_BYTES_INIT", (long) DATASET_BYTES_INIT);
|
||||
PyModule_AddIntConstant(module, "DATASET_BYTES_GROWTH", (long) DATASET_BYTES_GROWTH);
|
||||
PyModule_AddIntConstant(module, "CACHE_BYTES_INIT", (long) CACHE_BYTES_INIT);
|
||||
PyModule_AddIntConstant(module, "CACHE_BYTES_GROWTH", (long) CACHE_BYTES_GROWTH);
|
||||
PyModule_AddIntConstant(module, "EPOCH_LENGTH", (long) EPOCH_LENGTH);
|
||||
PyModule_AddIntConstant(module, "MIX_BYTES", (long) MIX_BYTES);
|
||||
PyModule_AddIntConstant(module, "HASH_BYTES", (long) HASH_BYTES);
|
||||
PyModule_AddIntConstant(module, "DATASET_PARENTS", (long) DATASET_PARENTS);
|
||||
PyModule_AddIntConstant(module, "CACHE_ROUNDS", (long) CACHE_ROUNDS);
|
||||
PyModule_AddIntConstant(module, "ACCESSES", (long) ACCESSES);
|
||||
}
|
||||
|
|
|
|||
56
Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.cpp
generated
vendored
56
Godeps/_workspace/src/github.com/ethereum/ethash/test/c/test.cpp
generated
vendored
|
|
@ -4,7 +4,9 @@
|
|||
#include <libethash/internal.h>
|
||||
|
||||
#ifdef WITH_CRYPTOPP
|
||||
|
||||
#include <libethash/sha3_cryptopp.h>
|
||||
|
||||
#else
|
||||
#include <libethash/sha3.h>
|
||||
#endif // WITH_CRYPTOPP
|
||||
|
|
@ -15,7 +17,7 @@
|
|||
#include <boost/test/unit_test.hpp>
|
||||
#include <iostream>
|
||||
|
||||
std::string bytesToHexString(const uint8_t *str, const size_t s) {
|
||||
std::string bytesToHexString(const uint8_t *str, const uint32_t s) {
|
||||
std::ostringstream ret;
|
||||
|
||||
for (int i = 0; i < s; ++i)
|
||||
|
|
@ -28,7 +30,7 @@ BOOST_AUTO_TEST_CASE(fnv_hash_check) {
|
|||
uint32_t x = 1235U;
|
||||
const uint32_t
|
||||
y = 9999999U,
|
||||
expected = (FNV_PRIME * x) ^ y;
|
||||
expected = (FNV_PRIME * x) ^y;
|
||||
|
||||
x = fnv_hash(x, y);
|
||||
|
||||
|
|
@ -65,22 +67,24 @@ BOOST_AUTO_TEST_CASE(SHA512_check) {
|
|||
BOOST_AUTO_TEST_CASE(ethash_params_init_genesis_check) {
|
||||
ethash_params params;
|
||||
ethash_params_init(¶ms, 0);
|
||||
BOOST_REQUIRE_MESSAGE(params.full_size < DAGSIZE_BYTES_INIT,
|
||||
BOOST_REQUIRE_MESSAGE(params.full_size < DATASET_BYTES_INIT,
|
||||
"\nfull size: " << params.full_size << "\n"
|
||||
<< "should be less than or equal to: " << DAGSIZE_BYTES_INIT << "\n");
|
||||
BOOST_REQUIRE_MESSAGE(params.full_size + 20*MIX_BYTES >= DAGSIZE_BYTES_INIT,
|
||||
"\nfull size + 20*MIX_BYTES: " << params.full_size + 20*MIX_BYTES << "\n"
|
||||
<< "should be greater than or equal to: " << DAGSIZE_BYTES_INIT << "\n");
|
||||
BOOST_REQUIRE_MESSAGE(params.cache_size < DAGSIZE_BYTES_INIT / 32,
|
||||
<< "should be less than or equal to: " << DATASET_BYTES_INIT << "\n");
|
||||
BOOST_REQUIRE_MESSAGE(params.full_size + 20 * MIX_BYTES >= DATASET_BYTES_INIT,
|
||||
"\nfull size + 20*MIX_BYTES: " << params.full_size + 20 * MIX_BYTES << "\n"
|
||||
<< "should be greater than or equal to: " << DATASET_BYTES_INIT << "\n");
|
||||
BOOST_REQUIRE_MESSAGE(params.cache_size < DATASET_BYTES_INIT / 32,
|
||||
"\ncache size: " << params.cache_size << "\n"
|
||||
<< "should be less than or equal to: " << DAGSIZE_BYTES_INIT / 32 << "\n");
|
||||
<< "should be less than or equal to: " << DATASET_BYTES_INIT / 32 << "\n");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ethash_params_init_genesis_calcifide_check) {
|
||||
ethash_params params;
|
||||
ethash_params_init(¶ms, 0);
|
||||
const uint32_t expected_full_size = 1073739904;
|
||||
const uint32_t expected_cache_size = 1048384;
|
||||
BOOST_REQUIRE_MESSAGE(ethash_params_init(¶ms, 0),
|
||||
"Params could not be initialized");
|
||||
const uint32_t
|
||||
expected_full_size = 1073739904,
|
||||
expected_cache_size = 16776896;
|
||||
BOOST_REQUIRE_MESSAGE(params.full_size == expected_full_size,
|
||||
"\nexpected: " << expected_cache_size << "\n"
|
||||
<< "actual: " << params.full_size << "\n");
|
||||
|
|
@ -91,17 +95,24 @@ BOOST_AUTO_TEST_CASE(ethash_params_init_genesis_calcifide_check) {
|
|||
|
||||
BOOST_AUTO_TEST_CASE(light_and_full_client_checks) {
|
||||
ethash_params params;
|
||||
uint8_t seed[32], hash[32];
|
||||
uint8_t seed[32], hash[32], difficulty[32];
|
||||
ethash_return_value light_out, full_out;
|
||||
memcpy(seed, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
|
||||
memcpy(hash, "~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~~~", 32);
|
||||
|
||||
// Set the difficulty
|
||||
difficulty[0] = 197;
|
||||
difficulty[1] = 90;
|
||||
for (int i = 2; i < 32; i++)
|
||||
difficulty[i] = (uint8_t) 255;
|
||||
|
||||
ethash_params_init(¶ms, 0);
|
||||
params.cache_size = 1024;
|
||||
params.full_size = 1024 * 32;
|
||||
ethash_cache cache;
|
||||
cache.mem = alloca(params.cache_size);
|
||||
ethash_mkcache(&cache, ¶ms, seed);
|
||||
node * full_mem = (node *) alloca(params.full_size);
|
||||
node *full_mem = (node *) alloca(params.full_size);
|
||||
ethash_compute_full_data(full_mem, ¶ms, &cache);
|
||||
|
||||
{
|
||||
|
|
@ -115,7 +126,6 @@ BOOST_AUTO_TEST_CASE(light_and_full_client_checks) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
node node;
|
||||
ethash_calculate_dag_item(&node, 0, ¶ms, &cache);
|
||||
|
|
@ -128,7 +138,7 @@ BOOST_AUTO_TEST_CASE(light_and_full_client_checks) {
|
|||
}
|
||||
|
||||
{
|
||||
for (int i = 0 ; i < params.full_size / sizeof(node) ; ++i ) {
|
||||
for (int i = 0; i < params.full_size / sizeof(node); ++i) {
|
||||
for (uint32_t j = 0; j < 32; ++j) {
|
||||
node expected_node;
|
||||
ethash_calculate_dag_item(&expected_node, j, ¶ms, &cache);
|
||||
|
|
@ -187,6 +197,12 @@ BOOST_AUTO_TEST_CASE(light_and_full_client_checks) {
|
|||
BOOST_REQUIRE_MESSAGE(full_mix_hash_string == light_mix_hash_string,
|
||||
"\nlight mix hash: " << light_mix_hash_string.c_str() << "\n"
|
||||
<< "full mix hash: " << full_mix_hash_string.c_str() << "\n");
|
||||
BOOST_REQUIRE_MESSAGE(ethash_check_difficulty(full_out.result, difficulty),
|
||||
"ethash_check_difficulty failed"
|
||||
);
|
||||
BOOST_REQUIRE_MESSAGE(ethash_quick_check_difficulty(hash, 5U, full_out.mix_hash, difficulty),
|
||||
"ethash_quick_check_difficulty failed"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,14 +215,14 @@ BOOST_AUTO_TEST_CASE(ethash_check_difficulty_check) {
|
|||
memcpy(target, "22222222222222222222222222222222", 32);
|
||||
BOOST_REQUIRE_MESSAGE(
|
||||
ethash_check_difficulty(hash, target),
|
||||
"\nexpected \"" << hash << "\" to have less difficulty than \"" << target << "\"\n");
|
||||
"\nexpected \"" << std::string((char *) hash, 32).c_str() << "\" to have the same or less difficulty than \"" << std::string((char *) target, 32).c_str() << "\"\n");
|
||||
BOOST_REQUIRE_MESSAGE(
|
||||
!ethash_check_difficulty(hash, hash),
|
||||
"\nexpected \"" << hash << "\" to have the same difficulty as \"" << hash << "\"\n");
|
||||
ethash_check_difficulty(hash, hash),
|
||||
"\nexpected \"" << hash << "\" to have the same or less difficulty than \"" << hash << "\"\n");
|
||||
memcpy(target, "11111111111111111111111111111112", 32);
|
||||
BOOST_REQUIRE_MESSAGE(
|
||||
ethash_check_difficulty(hash, target),
|
||||
"\nexpected \"" << hash << "\" to have less difficulty than \"" << target << "\"\n");
|
||||
"\nexpected \"" << hash << "\" to have the same or less difficulty than \"" << target << "\"\n");
|
||||
memcpy(target, "11111111111111111111111111111110", 32);
|
||||
BOOST_REQUIRE_MESSAGE(
|
||||
!ethash_check_difficulty(hash, target),
|
||||
|
|
|
|||
82
Godeps/_workspace/src/github.com/ethereum/ethash/test/go/ethash_test.go
generated
vendored
Normal file
82
Godeps/_workspace/src/github.com/ethereum/ethash/test/go/ethash_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
package ethashTest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"log"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/ethash"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
)
|
||||
|
||||
func TestEthash(t *testing.T) {
|
||||
seedHash := make([]byte, 32)
|
||||
_, err := rand.Read(seedHash)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
db, err := ethdb.NewMemDatabase()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
blockProcessor, err := core.NewCanonical(5, db)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
log.Println("Block Number: ", blockProcessor.ChainManager().CurrentBlock().Number())
|
||||
|
||||
e := ethash.New(blockProcessor.ChainManager())
|
||||
|
||||
miningHash := make([]byte, 32)
|
||||
if _, err := rand.Read(miningHash); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
diff := big.NewInt(10000)
|
||||
log.Println("difficulty", diff)
|
||||
|
||||
nonce := uint64(0)
|
||||
|
||||
ghash_full := e.FullHash(nonce, miningHash)
|
||||
log.Printf("ethash full (on nonce): %x %x\n", ghash_full, nonce)
|
||||
|
||||
ghash_light := e.LightHash(nonce, miningHash)
|
||||
log.Printf("ethash light (on nonce): %x %x\n", ghash_light, nonce)
|
||||
|
||||
if bytes.Compare(ghash_full, ghash_light) != 0 {
|
||||
t.Errorf("full: %x, light: %x", ghash_full, ghash_light)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSeedHash(t *testing.T) {
|
||||
seed0, err := ethash.GetSeedHash(0)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to get seedHash for block 0: %v", err)
|
||||
}
|
||||
if bytes.Compare(seed0, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) != 0 {
|
||||
log.Printf("seedHash for block 0 should be 0s, was: %v\n", seed0)
|
||||
}
|
||||
seed1, err := ethash.GetSeedHash(30000)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// From python:
|
||||
// > from pyethash import get_seedhash
|
||||
// > get_seedhash(30000)
|
||||
expectedSeed1, err := hex.DecodeString("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if bytes.Compare(seed1, expectedSeed1) != 0 {
|
||||
log.Printf("seedHash for block 1 should be: %v,\nactual value: %v\n", expectedSeed1, seed1)
|
||||
}
|
||||
|
||||
}
|
||||
20
Godeps/_workspace/src/github.com/ethereum/ethash/test/go/test.sh
generated
vendored
Normal file
20
Godeps/_workspace/src/github.com/ethereum/ethash/test/go/test.sh
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Strict mode
|
||||
set -e
|
||||
|
||||
SOURCE="${BASH_SOURCE[0]}"
|
||||
while [ -h "$SOURCE" ]; do
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
SOURCE="$(readlink "$SOURCE")"
|
||||
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
|
||||
done
|
||||
TEST_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
|
||||
export GOPATH=${HOME}/.go
|
||||
export PATH=$PATH:$GOPATH/bin
|
||||
echo "# getting go dependencies (can take some time)..."
|
||||
cd ${TEST_DIR}/../.. && go get
|
||||
cd ${GOPATH}/src/github.com/ethereum/go-ethereum
|
||||
git checkout poc-9
|
||||
cd ${TEST_DIR} && go test
|
||||
1
Godeps/_workspace/src/github.com/ethereum/ethash/test/python/requirements.txt
generated
vendored
1
Godeps/_workspace/src/github.com/ethereum/ethash/test/python/requirements.txt
generated
vendored
|
|
@ -1,2 +1,3 @@
|
|||
pyethereum==0.7.522
|
||||
nose==1.3.4
|
||||
pysha3==0.3
|
||||
4
Godeps/_workspace/src/github.com/ethereum/ethash/test/python/test.sh
generated
vendored
4
Godeps/_workspace/src/github.com/ethereum/ethash/test/python/test.sh
generated
vendored
|
|
@ -14,6 +14,6 @@ TEST_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
|||
[ -d $TEST_DIR/python-virtual-env ] || virtualenv --system-site-packages $TEST_DIR/python-virtual-env
|
||||
source $TEST_DIR/python-virtual-env/bin/activate
|
||||
pip install -r $TEST_DIR/requirements.txt > /dev/null
|
||||
pip install -e $TEST_DIR/../.. > /dev/null
|
||||
pip install --upgrade --no-deps --force-reinstall -e $TEST_DIR/../..
|
||||
cd $TEST_DIR
|
||||
nosetests --with-doctest -v
|
||||
nosetests --with-doctest -v --nocapture
|
||||
|
|
|
|||
104
Godeps/_workspace/src/github.com/ethereum/ethash/test/python/test_pyethash.py
generated
vendored
104
Godeps/_workspace/src/github.com/ethereum/ethash/test/python/test_pyethash.py
generated
vendored
|
|
@ -4,42 +4,102 @@ from random import randint
|
|||
def test_get_cache_size_not_None():
|
||||
for _ in range(100):
|
||||
block_num = randint(0,12456789)
|
||||
out = pyethash.core.get_cache_size(block_num)
|
||||
out = pyethash.get_cache_size(block_num)
|
||||
assert out != None
|
||||
|
||||
def test_get_full_size_not_None():
|
||||
for _ in range(100):
|
||||
block_num = randint(0,12456789)
|
||||
out = pyethash.core.get_full_size(block_num)
|
||||
out = pyethash.get_full_size(block_num)
|
||||
assert out != None
|
||||
|
||||
def test_get_cache_size_based_on_EPOCH():
|
||||
for _ in range(100):
|
||||
block_num = randint(0,12456789)
|
||||
out1 = pyethash.core.get_cache_size(block_num)
|
||||
out2 = pyethash.core.get_cache_size((block_num // pyethash.EPOCH_LENGTH) * pyethash.EPOCH_LENGTH)
|
||||
out1 = pyethash.get_cache_size(block_num)
|
||||
out2 = pyethash.get_cache_size((block_num // pyethash.EPOCH_LENGTH) * pyethash.EPOCH_LENGTH)
|
||||
assert out1 == out2
|
||||
|
||||
def test_get_full_size_based_on_EPOCH():
|
||||
for _ in range(100):
|
||||
block_num = randint(0,12456789)
|
||||
out1 = pyethash.core.get_full_size(block_num)
|
||||
out2 = pyethash.core.get_full_size((block_num // pyethash.EPOCH_LENGTH) * pyethash.EPOCH_LENGTH)
|
||||
out1 = pyethash.get_full_size(block_num)
|
||||
out2 = pyethash.get_full_size((block_num // pyethash.EPOCH_LENGTH) * pyethash.EPOCH_LENGTH)
|
||||
assert out1 == out2
|
||||
|
||||
#def test_get_params_based_on_EPOCH():
|
||||
# block_num = 123456
|
||||
# out1 = pyethash.core.get_params(block_num)
|
||||
# out2 = pyethash.core.get_params((block_num // pyethash.EPOCH_LENGTH) * pyethash.EPOCH_LENGTH)
|
||||
# assert out1["DAG Size"] == out2["DAG Size"]
|
||||
# assert out1["Cache Size"] == out2["Cache Size"]
|
||||
#
|
||||
#def test_get_params_returns_different_values_based_on_different_block_input():
|
||||
# out1 = pyethash.core.get_params(123456)
|
||||
# out2 = pyethash.core.get_params(12345)
|
||||
# assert out1["DAG Size"] != out2["DAG Size"]
|
||||
# assert out1["Cache Size"] != out2["Cache Size"]
|
||||
#
|
||||
#def test_get_cache_smoke_test():
|
||||
# params = pyethash.core.get_params(123456)
|
||||
# assert pyethash.core.mkcache(params, "~~~~") != None
|
||||
# See light_and_full_client_checks in test.cpp
|
||||
def test_mkcache_is_as_expected():
|
||||
actual = pyethash.mkcache_bytes(
|
||||
1024,
|
||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~").encode('hex')
|
||||
expected = "2da2b506f21070e1143d908e867962486d6b0a02e31d468fd5e3a7143aafa76a14201f63374314e2a6aaf84ad2eb57105dea3378378965a1b3873453bb2b78f9a8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995c259440b89fa3481c2c33171477c305c8e1e421f8d8f6d59585449d0034f3e421808d8da6bbd0b6378f567647cc6c4ba6c434592b198ad444e7284905b7c6adaf70bf43ec2daa7bd5e8951aa609ab472c124cf9eba3d38cff5091dc3f58409edcc386c743c3bd66f92408796ee1e82dd149eaefbf52b00ce33014a6eb3e50625413b072a58bc01da28262f42cbe4f87d4abc2bf287d15618405a1fe4e386fcdafbb171064bd99901d8f81dd6789396ce5e364ac944bbbd75a7827291c70b42d26385910cd53ca535ab29433dd5c5714d26e0dce95514c5ef866329c12e958097e84462197c2b32087849dab33e88b11da61d52f9dbc0b92cc61f742c07dbbf751c49d7678624ee60dfbe62e5e8c47a03d8247643f3d16ad8c8e663953bcda1f59d7e2d4a9bf0768e789432212621967a8f41121ad1df6ae1fa78782530695414c6213942865b2730375019105cae91a4c17a558d4b63059661d9f108362143107babe0b848de412e4da59168cce82bfbff3c99e022dd6ac1e559db991f2e3f7bb910cefd173e65ed00a8d5d416534e2c8416ff23977dbf3eb7180b75c71580d08ce95efeb9b0afe904ea12285a392aff0c8561ff79fca67f694a62b9e52377485c57cc3598d84cac0a9d27960de0cc31ff9bbfe455acaa62c8aa5d2cce96f345da9afe843d258a99c4eaf3650fc62efd81c7b81cd0d534d2d71eeda7a6e315d540b4473c80f8730037dc2ae3e47b986240cfc65ccc565f0d8cde0bc68a57e39a271dda57440b3598bee19f799611d25731a96b5dbbbefdff6f4f656161462633030d62560ea4e9c161cf78fc96a2ca5aaa32453a6c5dea206f766244e8c9d9a8dc61185ce37f1fc804459c5f07434f8ecb34141b8dcae7eae704c950b55556c5f40140c3714b45eddb02637513268778cbf937a33e4e33183685f9deb31ef54e90161e76d969587dd782eaa94e289420e7c2ee908517f5893a26fdb5873d68f92d118d4bcf98d7a4916794d6ab290045e30f9ea00ca547c584b8482b0331ba1539a0f2714fddc3a0b06b0cfbb6a607b8339c39bcfd6640b1f653e9d70ef6c985b"
|
||||
assert actual == expected
|
||||
|
||||
def test_calc_dataset_is_not_None():
|
||||
cache = pyethash.mkcache_bytes(
|
||||
1024,
|
||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
|
||||
assert pyethash.calc_dataset_bytes(1024 * 32, cache) != None
|
||||
|
||||
def test_light_and_full_agree():
|
||||
cache = pyethash.mkcache_bytes(
|
||||
1024,
|
||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
|
||||
full_size = 1024 * 32
|
||||
header = "~~~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
light_result = pyethash.hashimoto_light(full_size, cache, header, 0)
|
||||
dataset = pyethash.calc_dataset_bytes(full_size, cache)
|
||||
full_result = pyethash.hashimoto_full(dataset, header, 0)
|
||||
assert light_result["mix digest"] != None
|
||||
assert len(light_result["mix digest"]) == 32
|
||||
assert light_result["mix digest"] == full_result["mix digest"]
|
||||
assert light_result["result"] != None
|
||||
assert len(light_result["result"]) == 32
|
||||
assert light_result["result"] == full_result["result"]
|
||||
|
||||
def int_to_bytes(i):
|
||||
b = []
|
||||
for _ in range(32):
|
||||
b.append(chr(i & 0xff))
|
||||
i >>= 8
|
||||
b.reverse()
|
||||
return "".join(b)
|
||||
|
||||
def test_mining_basic():
|
||||
easy_difficulty = int_to_bytes(2**256 - 1)
|
||||
assert easy_difficulty.encode('hex') == 'f' * 64
|
||||
cache = pyethash.mkcache_bytes(
|
||||
1024,
|
||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
|
||||
full_size = 1024 * 32
|
||||
header = "~~~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
dataset = pyethash.calc_dataset_bytes(full_size, cache)
|
||||
# Check type of outputs
|
||||
assert type(pyethash.mine(dataset,header,easy_difficulty)) == dict
|
||||
assert type(pyethash.mine(dataset,header,easy_difficulty)["nonce"]) == long
|
||||
assert type(pyethash.mine(dataset,header,easy_difficulty)["mix digest"]) == str
|
||||
assert type(pyethash.mine(dataset,header,easy_difficulty)["result"]) == str
|
||||
|
||||
def test_mining_doesnt_always_return_the_same_value():
|
||||
easy_difficulty1 = int_to_bytes(int(2**256 * 0.999))
|
||||
# 1 in 1000 difficulty
|
||||
easy_difficulty2 = int_to_bytes(int(2**256 * 0.001))
|
||||
assert easy_difficulty1 != easy_difficulty2
|
||||
cache = pyethash.mkcache_bytes(
|
||||
1024,
|
||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
|
||||
full_size = 1024 * 32
|
||||
header = "~~~~~X~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
dataset = pyethash.calc_dataset_bytes(full_size, cache)
|
||||
# Check type of outputs
|
||||
assert pyethash.mine(dataset, header, easy_difficulty1)['nonce'] != pyethash.mine(dataset, header, easy_difficulty2)['nonce']
|
||||
|
||||
def test_get_seedhash():
|
||||
assert pyethash.get_seedhash(0).encode('hex') == '0' * 64
|
||||
import hashlib, sha3
|
||||
expected = pyethash.get_seedhash(0)
|
||||
#print "checking seed hashes:",
|
||||
for i in range(0, 30000*2048, 30000):
|
||||
#print i // 30000,
|
||||
assert pyethash.get_seedhash(i) == expected
|
||||
expected = hashlib.sha3_256(expected).digest()
|
||||
|
|
|
|||
4
Godeps/_workspace/src/github.com/ethereum/ethash/test/test.sh
generated
vendored
4
Godeps/_workspace/src/github.com/ethereum/ethash/test/test.sh
generated
vendored
|
|
@ -14,7 +14,9 @@ TEST_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
|||
echo -e "\n################# Testing JS ##################"
|
||||
# TODO: Use mocha and real testing tools instead of rolling our own
|
||||
cd $TEST_DIR/../js
|
||||
node test.js
|
||||
if [ -x "$(which npm)" ] ; then
|
||||
npm test
|
||||
fi
|
||||
|
||||
echo -e "\n################# Testing C ##################"
|
||||
$TEST_DIR/c/test.sh
|
||||
|
|
|
|||
1066
Godeps/_workspace/src/github.com/obscuren/otto/ast/README.markdown
generated
vendored
1066
Godeps/_workspace/src/github.com/obscuren/otto/ast/README.markdown
generated
vendored
File diff suppressed because it is too large
Load diff
496
Godeps/_workspace/src/github.com/obscuren/otto/ast/node.go
generated
vendored
496
Godeps/_workspace/src/github.com/obscuren/otto/ast/node.go
generated
vendored
|
|
@ -1,496 +0,0 @@
|
|||
/*
|
||||
Package ast declares types representing a JavaScript AST.
|
||||
|
||||
Warning
|
||||
|
||||
The parser and AST interfaces are still works-in-progress (particularly where
|
||||
node types are concerned) and may change in the future.
|
||||
|
||||
*/
|
||||
package ast
|
||||
|
||||
import (
|
||||
"github.com/robertkrimen/otto/file"
|
||||
"github.com/robertkrimen/otto/token"
|
||||
)
|
||||
|
||||
// All nodes implement the Node interface.
|
||||
type Node interface {
|
||||
Idx0() file.Idx // The index of the first character belonging to the node
|
||||
Idx1() file.Idx // The index of the first character immediately after the node
|
||||
}
|
||||
|
||||
// ========== //
|
||||
// Expression //
|
||||
// ========== //
|
||||
|
||||
type (
|
||||
// All expression nodes implement the Expression interface.
|
||||
Expression interface {
|
||||
Node
|
||||
_expressionNode()
|
||||
}
|
||||
|
||||
ArrayLiteral struct {
|
||||
LeftBracket file.Idx
|
||||
RightBracket file.Idx
|
||||
Value []Expression
|
||||
}
|
||||
|
||||
AssignExpression struct {
|
||||
Operator token.Token
|
||||
Left Expression
|
||||
Right Expression
|
||||
}
|
||||
|
||||
BadExpression struct {
|
||||
From file.Idx
|
||||
To file.Idx
|
||||
}
|
||||
|
||||
BinaryExpression struct {
|
||||
Operator token.Token
|
||||
Left Expression
|
||||
Right Expression
|
||||
Comparison bool
|
||||
}
|
||||
|
||||
BooleanLiteral struct {
|
||||
Idx file.Idx
|
||||
Literal string
|
||||
Value bool
|
||||
}
|
||||
|
||||
BracketExpression struct {
|
||||
Left Expression
|
||||
Member Expression
|
||||
LeftBracket file.Idx
|
||||
RightBracket file.Idx
|
||||
}
|
||||
|
||||
CallExpression struct {
|
||||
Callee Expression
|
||||
LeftParenthesis file.Idx
|
||||
ArgumentList []Expression
|
||||
RightParenthesis file.Idx
|
||||
}
|
||||
|
||||
ConditionalExpression struct {
|
||||
Test Expression
|
||||
Consequent Expression
|
||||
Alternate Expression
|
||||
}
|
||||
|
||||
DotExpression struct {
|
||||
Left Expression
|
||||
Identifier Identifier
|
||||
}
|
||||
|
||||
FunctionLiteral struct {
|
||||
Function file.Idx
|
||||
Name *Identifier
|
||||
ParameterList *ParameterList
|
||||
Body Statement
|
||||
Source string
|
||||
|
||||
DeclarationList []Declaration
|
||||
}
|
||||
|
||||
Identifier struct {
|
||||
Name string
|
||||
Idx file.Idx
|
||||
}
|
||||
|
||||
NewExpression struct {
|
||||
New file.Idx
|
||||
Callee Expression
|
||||
LeftParenthesis file.Idx
|
||||
ArgumentList []Expression
|
||||
RightParenthesis file.Idx
|
||||
}
|
||||
|
||||
NullLiteral struct {
|
||||
Idx file.Idx
|
||||
Literal string
|
||||
}
|
||||
|
||||
NumberLiteral struct {
|
||||
Idx file.Idx
|
||||
Literal string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
ObjectLiteral struct {
|
||||
LeftBrace file.Idx
|
||||
RightBrace file.Idx
|
||||
Value []Property
|
||||
}
|
||||
|
||||
ParameterList struct {
|
||||
Opening file.Idx
|
||||
List []*Identifier
|
||||
Closing file.Idx
|
||||
}
|
||||
|
||||
Property struct {
|
||||
Key string
|
||||
Kind string
|
||||
Value Expression
|
||||
}
|
||||
|
||||
RegExpLiteral struct {
|
||||
Idx file.Idx
|
||||
Literal string
|
||||
Pattern string
|
||||
Flags string
|
||||
Value string
|
||||
}
|
||||
|
||||
SequenceExpression struct {
|
||||
Sequence []Expression
|
||||
}
|
||||
|
||||
StringLiteral struct {
|
||||
Idx file.Idx
|
||||
Literal string
|
||||
Value string
|
||||
}
|
||||
|
||||
ThisExpression struct {
|
||||
Idx file.Idx
|
||||
}
|
||||
|
||||
UnaryExpression struct {
|
||||
Operator token.Token
|
||||
Idx file.Idx // If a prefix operation
|
||||
Operand Expression
|
||||
Postfix bool
|
||||
}
|
||||
|
||||
VariableExpression struct {
|
||||
Name string
|
||||
Idx file.Idx
|
||||
Initializer Expression
|
||||
}
|
||||
)
|
||||
|
||||
// _expressionNode
|
||||
|
||||
func (*ArrayLiteral) _expressionNode() {}
|
||||
func (*AssignExpression) _expressionNode() {}
|
||||
func (*BadExpression) _expressionNode() {}
|
||||
func (*BinaryExpression) _expressionNode() {}
|
||||
func (*BooleanLiteral) _expressionNode() {}
|
||||
func (*BracketExpression) _expressionNode() {}
|
||||
func (*CallExpression) _expressionNode() {}
|
||||
func (*ConditionalExpression) _expressionNode() {}
|
||||
func (*DotExpression) _expressionNode() {}
|
||||
func (*FunctionLiteral) _expressionNode() {}
|
||||
func (*Identifier) _expressionNode() {}
|
||||
func (*NewExpression) _expressionNode() {}
|
||||
func (*NullLiteral) _expressionNode() {}
|
||||
func (*NumberLiteral) _expressionNode() {}
|
||||
func (*ObjectLiteral) _expressionNode() {}
|
||||
func (*RegExpLiteral) _expressionNode() {}
|
||||
func (*SequenceExpression) _expressionNode() {}
|
||||
func (*StringLiteral) _expressionNode() {}
|
||||
func (*ThisExpression) _expressionNode() {}
|
||||
func (*UnaryExpression) _expressionNode() {}
|
||||
func (*VariableExpression) _expressionNode() {}
|
||||
|
||||
// ========= //
|
||||
// Statement //
|
||||
// ========= //
|
||||
|
||||
type (
|
||||
// All statement nodes implement the Statement interface.
|
||||
Statement interface {
|
||||
Node
|
||||
_statementNode()
|
||||
}
|
||||
|
||||
BadStatement struct {
|
||||
From file.Idx
|
||||
To file.Idx
|
||||
}
|
||||
|
||||
BlockStatement struct {
|
||||
LeftBrace file.Idx
|
||||
List []Statement
|
||||
RightBrace file.Idx
|
||||
}
|
||||
|
||||
BranchStatement struct {
|
||||
Idx file.Idx
|
||||
Token token.Token
|
||||
Label *Identifier
|
||||
}
|
||||
|
||||
CaseStatement struct {
|
||||
Case file.Idx
|
||||
Test Expression
|
||||
Consequent []Statement
|
||||
}
|
||||
|
||||
CatchStatement struct {
|
||||
Catch file.Idx
|
||||
Parameter *Identifier
|
||||
Body Statement
|
||||
}
|
||||
|
||||
DebuggerStatement struct {
|
||||
Debugger file.Idx
|
||||
}
|
||||
|
||||
DoWhileStatement struct {
|
||||
Do file.Idx
|
||||
Test Expression
|
||||
Body Statement
|
||||
}
|
||||
|
||||
EmptyStatement struct {
|
||||
Semicolon file.Idx
|
||||
}
|
||||
|
||||
ExpressionStatement struct {
|
||||
Expression Expression
|
||||
}
|
||||
|
||||
ForInStatement struct {
|
||||
For file.Idx
|
||||
Into Expression
|
||||
Source Expression
|
||||
Body Statement
|
||||
}
|
||||
|
||||
ForStatement struct {
|
||||
For file.Idx
|
||||
Initializer Expression
|
||||
Update Expression
|
||||
Test Expression
|
||||
Body Statement
|
||||
}
|
||||
|
||||
IfStatement struct {
|
||||
If file.Idx
|
||||
Test Expression
|
||||
Consequent Statement
|
||||
Alternate Statement
|
||||
}
|
||||
|
||||
LabelledStatement struct {
|
||||
Label *Identifier
|
||||
Colon file.Idx
|
||||
Statement Statement
|
||||
}
|
||||
|
||||
ReturnStatement struct {
|
||||
Return file.Idx
|
||||
Argument Expression
|
||||
}
|
||||
|
||||
SwitchStatement struct {
|
||||
Switch file.Idx
|
||||
Discriminant Expression
|
||||
Default int
|
||||
Body []*CaseStatement
|
||||
}
|
||||
|
||||
ThrowStatement struct {
|
||||
Throw file.Idx
|
||||
Argument Expression
|
||||
}
|
||||
|
||||
TryStatement struct {
|
||||
Try file.Idx
|
||||
Body Statement
|
||||
Catch *CatchStatement
|
||||
Finally Statement
|
||||
}
|
||||
|
||||
VariableStatement struct {
|
||||
Var file.Idx
|
||||
List []Expression
|
||||
}
|
||||
|
||||
WhileStatement struct {
|
||||
While file.Idx
|
||||
Test Expression
|
||||
Body Statement
|
||||
}
|
||||
|
||||
WithStatement struct {
|
||||
With file.Idx
|
||||
Object Expression
|
||||
Body Statement
|
||||
}
|
||||
)
|
||||
|
||||
// _statementNode
|
||||
|
||||
func (*BadStatement) _statementNode() {}
|
||||
func (*BlockStatement) _statementNode() {}
|
||||
func (*BranchStatement) _statementNode() {}
|
||||
func (*CaseStatement) _statementNode() {}
|
||||
func (*CatchStatement) _statementNode() {}
|
||||
func (*DebuggerStatement) _statementNode() {}
|
||||
func (*DoWhileStatement) _statementNode() {}
|
||||
func (*EmptyStatement) _statementNode() {}
|
||||
func (*ExpressionStatement) _statementNode() {}
|
||||
func (*ForInStatement) _statementNode() {}
|
||||
func (*ForStatement) _statementNode() {}
|
||||
func (*IfStatement) _statementNode() {}
|
||||
func (*LabelledStatement) _statementNode() {}
|
||||
func (*ReturnStatement) _statementNode() {}
|
||||
func (*SwitchStatement) _statementNode() {}
|
||||
func (*ThrowStatement) _statementNode() {}
|
||||
func (*TryStatement) _statementNode() {}
|
||||
func (*VariableStatement) _statementNode() {}
|
||||
func (*WhileStatement) _statementNode() {}
|
||||
func (*WithStatement) _statementNode() {}
|
||||
|
||||
// =========== //
|
||||
// Declaration //
|
||||
// =========== //
|
||||
|
||||
type (
|
||||
// All declaration nodes implement the Declaration interface.
|
||||
Declaration interface {
|
||||
_declarationNode()
|
||||
}
|
||||
|
||||
FunctionDeclaration struct {
|
||||
Function *FunctionLiteral
|
||||
}
|
||||
|
||||
VariableDeclaration struct {
|
||||
Var file.Idx
|
||||
List []*VariableExpression
|
||||
}
|
||||
)
|
||||
|
||||
// _declarationNode
|
||||
|
||||
func (*FunctionDeclaration) _declarationNode() {}
|
||||
func (*VariableDeclaration) _declarationNode() {}
|
||||
|
||||
// ==== //
|
||||
// Node //
|
||||
// ==== //
|
||||
|
||||
type Program struct {
|
||||
Body []Statement
|
||||
|
||||
DeclarationList []Declaration
|
||||
}
|
||||
|
||||
// ==== //
|
||||
// Idx0 //
|
||||
// ==== //
|
||||
|
||||
func (self *ArrayLiteral) Idx0() file.Idx { return self.LeftBracket }
|
||||
func (self *AssignExpression) Idx0() file.Idx { return self.Left.Idx0() }
|
||||
func (self *BadExpression) Idx0() file.Idx { return self.From }
|
||||
func (self *BinaryExpression) Idx0() file.Idx { return self.Left.Idx0() }
|
||||
func (self *BooleanLiteral) Idx0() file.Idx { return self.Idx }
|
||||
func (self *BracketExpression) Idx0() file.Idx { return self.Left.Idx0() }
|
||||
func (self *CallExpression) Idx0() file.Idx { return self.Callee.Idx0() }
|
||||
func (self *ConditionalExpression) Idx0() file.Idx { return self.Test.Idx0() }
|
||||
func (self *DotExpression) Idx0() file.Idx { return self.Left.Idx0() }
|
||||
func (self *FunctionLiteral) Idx0() file.Idx { return self.Function }
|
||||
func (self *Identifier) Idx0() file.Idx { return self.Idx }
|
||||
func (self *NewExpression) Idx0() file.Idx { return self.New }
|
||||
func (self *NullLiteral) Idx0() file.Idx { return self.Idx }
|
||||
func (self *NumberLiteral) Idx0() file.Idx { return self.Idx }
|
||||
func (self *ObjectLiteral) Idx0() file.Idx { return self.LeftBrace }
|
||||
func (self *RegExpLiteral) Idx0() file.Idx { return self.Idx }
|
||||
func (self *SequenceExpression) Idx0() file.Idx { return self.Sequence[0].Idx0() }
|
||||
func (self *StringLiteral) Idx0() file.Idx { return self.Idx }
|
||||
func (self *ThisExpression) Idx0() file.Idx { return self.Idx }
|
||||
func (self *UnaryExpression) Idx0() file.Idx { return self.Idx }
|
||||
func (self *VariableExpression) Idx0() file.Idx { return self.Idx }
|
||||
|
||||
func (self *BadStatement) Idx0() file.Idx { return self.From }
|
||||
func (self *BlockStatement) Idx0() file.Idx { return self.LeftBrace }
|
||||
func (self *BranchStatement) Idx0() file.Idx { return self.Idx }
|
||||
func (self *CaseStatement) Idx0() file.Idx { return self.Case }
|
||||
func (self *CatchStatement) Idx0() file.Idx { return self.Catch }
|
||||
func (self *DebuggerStatement) Idx0() file.Idx { return self.Debugger }
|
||||
func (self *DoWhileStatement) Idx0() file.Idx { return self.Do }
|
||||
func (self *EmptyStatement) Idx0() file.Idx { return self.Semicolon }
|
||||
func (self *ExpressionStatement) Idx0() file.Idx { return self.Expression.Idx0() }
|
||||
func (self *ForInStatement) Idx0() file.Idx { return self.For }
|
||||
func (self *ForStatement) Idx0() file.Idx { return self.For }
|
||||
func (self *IfStatement) Idx0() file.Idx { return self.If }
|
||||
func (self *LabelledStatement) Idx0() file.Idx { return self.Label.Idx0() }
|
||||
func (self *Program) Idx0() file.Idx { return self.Body[0].Idx0() }
|
||||
func (self *ReturnStatement) Idx0() file.Idx { return self.Return }
|
||||
func (self *SwitchStatement) Idx0() file.Idx { return self.Switch }
|
||||
func (self *ThrowStatement) Idx0() file.Idx { return self.Throw }
|
||||
func (self *TryStatement) Idx0() file.Idx { return self.Try }
|
||||
func (self *VariableStatement) Idx0() file.Idx { return self.Var }
|
||||
func (self *WhileStatement) Idx0() file.Idx { return self.While }
|
||||
func (self *WithStatement) Idx0() file.Idx { return self.With }
|
||||
|
||||
// ==== //
|
||||
// Idx1 //
|
||||
// ==== //
|
||||
|
||||
func (self *ArrayLiteral) Idx1() file.Idx { return self.RightBracket }
|
||||
func (self *AssignExpression) Idx1() file.Idx { return self.Right.Idx1() }
|
||||
func (self *BadExpression) Idx1() file.Idx { return self.To }
|
||||
func (self *BinaryExpression) Idx1() file.Idx { return self.Right.Idx1() }
|
||||
func (self *BooleanLiteral) Idx1() file.Idx { return file.Idx(int(self.Idx) + len(self.Literal)) }
|
||||
func (self *BracketExpression) Idx1() file.Idx { return self.RightBracket + 1 }
|
||||
func (self *CallExpression) Idx1() file.Idx { return self.RightParenthesis + 1 }
|
||||
func (self *ConditionalExpression) Idx1() file.Idx { return self.Test.Idx1() }
|
||||
func (self *DotExpression) Idx1() file.Idx { return self.Identifier.Idx1() }
|
||||
func (self *FunctionLiteral) Idx1() file.Idx { return self.Body.Idx1() }
|
||||
func (self *Identifier) Idx1() file.Idx { return file.Idx(int(self.Idx) + len(self.Name)) }
|
||||
func (self *NewExpression) Idx1() file.Idx { return self.RightParenthesis + 1 }
|
||||
func (self *NullLiteral) Idx1() file.Idx { return file.Idx(int(self.Idx) + 4) } // "null"
|
||||
func (self *NumberLiteral) Idx1() file.Idx { return file.Idx(int(self.Idx) + len(self.Literal)) }
|
||||
func (self *ObjectLiteral) Idx1() file.Idx { return self.RightBrace }
|
||||
func (self *RegExpLiteral) Idx1() file.Idx { return file.Idx(int(self.Idx) + len(self.Literal)) }
|
||||
func (self *SequenceExpression) Idx1() file.Idx { return self.Sequence[0].Idx1() }
|
||||
func (self *StringLiteral) Idx1() file.Idx { return file.Idx(int(self.Idx) + len(self.Literal)) }
|
||||
func (self *ThisExpression) Idx1() file.Idx { return self.Idx }
|
||||
func (self *UnaryExpression) Idx1() file.Idx {
|
||||
if self.Postfix {
|
||||
return self.Operand.Idx1() + 2 // ++ --
|
||||
}
|
||||
return self.Operand.Idx1()
|
||||
}
|
||||
func (self *VariableExpression) Idx1() file.Idx {
|
||||
if self.Initializer == nil {
|
||||
return file.Idx(int(self.Idx) + len(self.Name) + 1)
|
||||
}
|
||||
return self.Initializer.Idx1()
|
||||
}
|
||||
|
||||
func (self *BadStatement) Idx1() file.Idx { return self.To }
|
||||
func (self *BlockStatement) Idx1() file.Idx { return self.RightBrace + 1 }
|
||||
func (self *BranchStatement) Idx1() file.Idx { return self.Idx }
|
||||
func (self *CaseStatement) Idx1() file.Idx { return self.Consequent[len(self.Consequent)-1].Idx1() }
|
||||
func (self *CatchStatement) Idx1() file.Idx { return self.Body.Idx1() }
|
||||
func (self *DebuggerStatement) Idx1() file.Idx { return self.Debugger + 8 }
|
||||
func (self *DoWhileStatement) Idx1() file.Idx { return self.Test.Idx1() }
|
||||
func (self *EmptyStatement) Idx1() file.Idx { return self.Semicolon + 1 }
|
||||
func (self *ExpressionStatement) Idx1() file.Idx { return self.Expression.Idx1() }
|
||||
func (self *ForInStatement) Idx1() file.Idx { return self.Body.Idx1() }
|
||||
func (self *ForStatement) Idx1() file.Idx { return self.Body.Idx1() }
|
||||
func (self *IfStatement) Idx1() file.Idx {
|
||||
if self.Alternate != nil {
|
||||
return self.Alternate.Idx1()
|
||||
}
|
||||
return self.Consequent.Idx1()
|
||||
}
|
||||
func (self *LabelledStatement) Idx1() file.Idx { return self.Colon + 1 }
|
||||
func (self *Program) Idx1() file.Idx { return self.Body[len(self.Body)-1].Idx1() }
|
||||
func (self *ReturnStatement) Idx1() file.Idx { return self.Return }
|
||||
func (self *SwitchStatement) Idx1() file.Idx { return self.Body[len(self.Body)-1].Idx1() }
|
||||
func (self *ThrowStatement) Idx1() file.Idx { return self.Throw }
|
||||
func (self *TryStatement) Idx1() file.Idx { return self.Try }
|
||||
func (self *VariableStatement) Idx1() file.Idx { return self.List[len(self.List)-1].Idx1() }
|
||||
func (self *WhileStatement) Idx1() file.Idx { return self.Body.Idx1() }
|
||||
func (self *WithStatement) Idx1() file.Idx { return self.Body.Idx1() }
|
||||
85
Godeps/_workspace/src/github.com/obscuren/otto/builtin_error.go
generated
vendored
85
Godeps/_workspace/src/github.com/obscuren/otto/builtin_error.go
generated
vendored
|
|
@ -1,85 +0,0 @@
|
|||
package otto
|
||||
|
||||
func (runtime *_runtime) newEvalError(message Value) *_object {
|
||||
self := runtime.newErrorObject(message)
|
||||
self.prototype = runtime.Global.EvalErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func builtinEvalError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newEvalError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewEvalError(self *_object, _ Value, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newEvalError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newTypeError(message Value) *_object {
|
||||
self := runtime.newErrorObject(message)
|
||||
self.prototype = runtime.Global.TypeErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func builtinTypeError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newTypeError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewTypeError(self *_object, _ Value, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newTypeError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newRangeError(message Value) *_object {
|
||||
self := runtime.newErrorObject(message)
|
||||
self.prototype = runtime.Global.RangeErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func builtinRangeError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newRangeError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewRangeError(self *_object, _ Value, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newRangeError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newURIError(message Value) *_object {
|
||||
self := runtime.newErrorObject(message)
|
||||
self.prototype = runtime.Global.URIErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newReferenceError(message Value) *_object {
|
||||
self := runtime.newErrorObject(message)
|
||||
self.prototype = runtime.Global.ReferenceErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func builtinReferenceError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newReferenceError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewReferenceError(self *_object, _ Value, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newReferenceError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newSyntaxError(message Value) *_object {
|
||||
self := runtime.newErrorObject(message)
|
||||
self.prototype = runtime.Global.SyntaxErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func builtinSyntaxError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newSyntaxError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewSyntaxError(self *_object, _ Value, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newSyntaxError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func builtinURIError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newURIError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewURIError(self *_object, _ Value, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newURIError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
144
Godeps/_workspace/src/github.com/obscuren/otto/clone.go
generated
vendored
144
Godeps/_workspace/src/github.com/obscuren/otto/clone.go
generated
vendored
|
|
@ -1,144 +0,0 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type _clone struct {
|
||||
runtime *_runtime
|
||||
stash struct {
|
||||
object map[*_object]*_object
|
||||
objectEnvironment map[*_objectEnvironment]*_objectEnvironment
|
||||
declarativeEnvironment map[*_declarativeEnvironment]*_declarativeEnvironment
|
||||
}
|
||||
}
|
||||
|
||||
func (runtime *_runtime) clone() *_runtime {
|
||||
|
||||
self := &_runtime{}
|
||||
clone := &_clone{
|
||||
runtime: self,
|
||||
}
|
||||
clone.stash.object = make(map[*_object]*_object)
|
||||
clone.stash.objectEnvironment = make(map[*_objectEnvironment]*_objectEnvironment)
|
||||
clone.stash.declarativeEnvironment = make(map[*_declarativeEnvironment]*_declarativeEnvironment)
|
||||
|
||||
globalObject := clone.object(runtime.GlobalObject)
|
||||
self.GlobalEnvironment = self.newObjectEnvironment(globalObject, nil)
|
||||
self.GlobalObject = globalObject
|
||||
self.Global = _global{
|
||||
clone.object(runtime.Global.Object),
|
||||
clone.object(runtime.Global.Function),
|
||||
clone.object(runtime.Global.Array),
|
||||
clone.object(runtime.Global.String),
|
||||
clone.object(runtime.Global.Boolean),
|
||||
clone.object(runtime.Global.Number),
|
||||
clone.object(runtime.Global.Math),
|
||||
clone.object(runtime.Global.Date),
|
||||
clone.object(runtime.Global.RegExp),
|
||||
clone.object(runtime.Global.Error),
|
||||
clone.object(runtime.Global.EvalError),
|
||||
clone.object(runtime.Global.TypeError),
|
||||
clone.object(runtime.Global.RangeError),
|
||||
clone.object(runtime.Global.ReferenceError),
|
||||
clone.object(runtime.Global.SyntaxError),
|
||||
clone.object(runtime.Global.URIError),
|
||||
clone.object(runtime.Global.JSON),
|
||||
|
||||
clone.object(runtime.Global.ObjectPrototype),
|
||||
clone.object(runtime.Global.FunctionPrototype),
|
||||
clone.object(runtime.Global.ArrayPrototype),
|
||||
clone.object(runtime.Global.StringPrototype),
|
||||
clone.object(runtime.Global.BooleanPrototype),
|
||||
clone.object(runtime.Global.NumberPrototype),
|
||||
clone.object(runtime.Global.DatePrototype),
|
||||
clone.object(runtime.Global.RegExpPrototype),
|
||||
clone.object(runtime.Global.ErrorPrototype),
|
||||
clone.object(runtime.Global.EvalErrorPrototype),
|
||||
clone.object(runtime.Global.TypeErrorPrototype),
|
||||
clone.object(runtime.Global.RangeErrorPrototype),
|
||||
clone.object(runtime.Global.ReferenceErrorPrototype),
|
||||
clone.object(runtime.Global.SyntaxErrorPrototype),
|
||||
clone.object(runtime.Global.URIErrorPrototype),
|
||||
}
|
||||
|
||||
self.EnterGlobalExecutionContext()
|
||||
|
||||
self.eval = self.GlobalObject.property["eval"].value.(Value).value.(*_object)
|
||||
self.GlobalObject.prototype = self.Global.ObjectPrototype
|
||||
|
||||
return self
|
||||
}
|
||||
func (clone *_clone) object(self0 *_object) *_object {
|
||||
if self1, exists := clone.stash.object[self0]; exists {
|
||||
return self1
|
||||
}
|
||||
self1 := &_object{}
|
||||
clone.stash.object[self0] = self1
|
||||
return self0.objectClass.clone(self0, self1, clone)
|
||||
}
|
||||
|
||||
func (clone *_clone) declarativeEnvironment(self0 *_declarativeEnvironment) (*_declarativeEnvironment, bool) {
|
||||
if self1, exists := clone.stash.declarativeEnvironment[self0]; exists {
|
||||
return self1, true
|
||||
}
|
||||
self1 := &_declarativeEnvironment{}
|
||||
clone.stash.declarativeEnvironment[self0] = self1
|
||||
return self1, false
|
||||
}
|
||||
|
||||
func (clone *_clone) objectEnvironment(self0 *_objectEnvironment) (*_objectEnvironment, bool) {
|
||||
if self1, exists := clone.stash.objectEnvironment[self0]; exists {
|
||||
return self1, true
|
||||
}
|
||||
self1 := &_objectEnvironment{}
|
||||
clone.stash.objectEnvironment[self0] = self1
|
||||
return self1, false
|
||||
}
|
||||
|
||||
func (clone *_clone) value(self0 Value) Value {
|
||||
self1 := self0
|
||||
switch value := self0.value.(type) {
|
||||
case *_object:
|
||||
self1.value = clone.object(value)
|
||||
}
|
||||
return self1
|
||||
}
|
||||
|
||||
func (clone *_clone) valueArray(self0 []Value) []Value {
|
||||
self1 := make([]Value, len(self0))
|
||||
for index, value := range self0 {
|
||||
self1[index] = clone.value(value)
|
||||
}
|
||||
return self1
|
||||
}
|
||||
|
||||
func (clone *_clone) environment(self0 _environment) _environment {
|
||||
if self0 == nil {
|
||||
return nil
|
||||
}
|
||||
return self0.clone(clone)
|
||||
}
|
||||
|
||||
func (clone *_clone) property(self0 _property) _property {
|
||||
self1 := self0
|
||||
if value, valid := self0.value.(Value); valid {
|
||||
self1.value = clone.value(value)
|
||||
} else {
|
||||
panic(fmt.Errorf("self0.value.(Value) != true"))
|
||||
}
|
||||
return self1
|
||||
}
|
||||
|
||||
func (clone *_clone) declarativeProperty(self0 _declarativeProperty) _declarativeProperty {
|
||||
self1 := self0
|
||||
self1.value = clone.value(self0.value)
|
||||
return self1
|
||||
}
|
||||
|
||||
func (clone *_clone) callFunction(self0 _callFunction) _callFunction {
|
||||
if self0 == nil {
|
||||
return nil
|
||||
}
|
||||
return self0.clone(clone)
|
||||
}
|
||||
46
Godeps/_workspace/src/github.com/obscuren/otto/cmpl_function.go
generated
vendored
46
Godeps/_workspace/src/github.com/obscuren/otto/cmpl_function.go
generated
vendored
|
|
@ -1,46 +0,0 @@
|
|||
package otto
|
||||
|
||||
// _cmpl_nodeCallFunction
|
||||
type _cmpl_nodeCallFunction struct {
|
||||
node *_nodeFunctionLiteral
|
||||
scopeEnvironment _environment // Can be either Lexical or Variable
|
||||
}
|
||||
|
||||
func new_nodeCallFunction(node *_nodeFunctionLiteral, scopeEnvironment _environment) *_cmpl_nodeCallFunction {
|
||||
self := &_cmpl_nodeCallFunction{
|
||||
node: node,
|
||||
}
|
||||
self.scopeEnvironment = scopeEnvironment
|
||||
return self
|
||||
}
|
||||
|
||||
func (self _cmpl_nodeCallFunction) Dispatch(function *_object, environment *_functionEnvironment, runtime *_runtime, this Value, argumentList []Value, _ bool) Value {
|
||||
return runtime.cmpl_call_nodeFunction(function, environment, self.node, this, argumentList)
|
||||
}
|
||||
|
||||
func (self _cmpl_nodeCallFunction) ScopeEnvironment() _environment {
|
||||
return self.scopeEnvironment
|
||||
}
|
||||
|
||||
func (self _cmpl_nodeCallFunction) Source(object *_object) string {
|
||||
return self.node.source
|
||||
}
|
||||
|
||||
func (self0 _cmpl_nodeCallFunction) clone(clone *_clone) _callFunction {
|
||||
return _cmpl_nodeCallFunction{
|
||||
node: self0.node,
|
||||
scopeEnvironment: clone.environment(self0.scopeEnvironment),
|
||||
}
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
func (runtime *_runtime) newNodeFunctionObject(node *_nodeFunctionLiteral, scopeEnvironment _environment) *_object {
|
||||
self := runtime.newClassObject("Function")
|
||||
self.value = _functionObject{
|
||||
call: new_nodeCallFunction(node, scopeEnvironment),
|
||||
construct: defaultConstructFunction,
|
||||
}
|
||||
self.defineProperty("length", toValue_int(len(node.parameterList)), 0000, false)
|
||||
return self
|
||||
}
|
||||
387
Godeps/_workspace/src/github.com/obscuren/otto/dbg/dbg.go
generated
vendored
387
Godeps/_workspace/src/github.com/obscuren/otto/dbg/dbg.go
generated
vendored
|
|
@ -1,387 +0,0 @@
|
|||
// This file was AUTOMATICALLY GENERATED by dbg-import (smuggol) from github.com/robertkrimen/dbg
|
||||
|
||||
/*
|
||||
Package dbg is a println/printf/log-debugging utility library.
|
||||
|
||||
import (
|
||||
Dbg "github.com/robertkrimen/dbg"
|
||||
)
|
||||
|
||||
dbg, dbgf := Dbg.New()
|
||||
|
||||
dbg("Emit some debug stuff", []byte{120, 121, 122, 122, 121}, math.Pi)
|
||||
# "2013/01/28 16:50:03 Emit some debug stuff [120 121 122 122 121] 3.141592653589793"
|
||||
|
||||
dbgf("With a %s formatting %.2f", "little", math.Pi)
|
||||
# "2013/01/28 16:51:55 With a little formatting (3.14)"
|
||||
|
||||
dbgf("%/fatal//A fatal debug statement: should not be here")
|
||||
# "A fatal debug statement: should not be here"
|
||||
# ...and then, os.Exit(1)
|
||||
|
||||
dbgf("%/panic//Can also panic %s", "this")
|
||||
# "Can also panic this"
|
||||
# ...as a panic, equivalent to: panic("Can also panic this")
|
||||
|
||||
dbgf("Any %s arguments without a corresponding %%", "extra", "are treated like arguments to dbg()")
|
||||
# "2013/01/28 17:14:40 Any extra arguments (without a corresponding %) are treated like arguments to dbg()"
|
||||
|
||||
dbgf("%d %d", 1, 2, 3, 4, 5)
|
||||
# "2013/01/28 17:16:32 Another example: 1 2 3 4 5"
|
||||
|
||||
dbgf("%@: Include the function name for a little context (via %s)", "%@")
|
||||
# "2013... github.com/robertkrimen/dbg.TestSynopsis: Include the function name for a little context (via %@)"
|
||||
|
||||
By default, dbg uses log (log.Println, log.Printf, log.Panic, etc.) for output.
|
||||
However, you can also provide your own output destination by invoking dbg.New with
|
||||
a customization function:
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
Dbg "github.com/robertkrimen/dbg"
|
||||
"os"
|
||||
)
|
||||
|
||||
# dbg to os.Stderr
|
||||
dbg, dbgf := Dbg.New(func(dbgr *Dbgr) {
|
||||
dbgr.SetOutput(os.Stderr)
|
||||
})
|
||||
|
||||
# A slightly contrived example:
|
||||
var buffer bytes.Buffer
|
||||
dbg, dbgf := New(func(dbgr *Dbgr) {
|
||||
dbgr.SetOutput(&buffer)
|
||||
})
|
||||
|
||||
*/
|
||||
package dbg
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type _frmt struct {
|
||||
ctl string
|
||||
format string
|
||||
operandCount int
|
||||
panic bool
|
||||
fatal bool
|
||||
check bool
|
||||
}
|
||||
|
||||
var (
|
||||
ctlTest = regexp.MustCompile(`^\s*%/`)
|
||||
ctlScan = regexp.MustCompile(`%?/(panic|fatal|check)(?:\s|$)`)
|
||||
)
|
||||
|
||||
func operandCount(format string) int {
|
||||
count := 0
|
||||
end := len(format)
|
||||
for at := 0; at < end; {
|
||||
for at < end && format[at] != '%' {
|
||||
at++
|
||||
}
|
||||
at++
|
||||
if at < end {
|
||||
if format[at] != '%' && format[at] != '@' {
|
||||
count++
|
||||
}
|
||||
at++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func parseFormat(format string) (frmt _frmt) {
|
||||
if ctlTest.MatchString(format) {
|
||||
format = strings.TrimLeftFunc(format, unicode.IsSpace)
|
||||
index := strings.Index(format, "//")
|
||||
if index != -1 {
|
||||
frmt.ctl = format[0:index]
|
||||
format = format[index+2:] // Skip the second slash via +2 (instead of +1)
|
||||
} else {
|
||||
frmt.ctl = format
|
||||
format = ""
|
||||
}
|
||||
for _, tmp := range ctlScan.FindAllStringSubmatch(frmt.ctl, -1) {
|
||||
for _, value := range tmp[1:] {
|
||||
switch value {
|
||||
case "panic":
|
||||
frmt.panic = true
|
||||
case "fatal":
|
||||
frmt.fatal = true
|
||||
case "check":
|
||||
frmt.check = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
frmt.format = format
|
||||
frmt.operandCount = operandCount(format)
|
||||
return
|
||||
}
|
||||
|
||||
type Dbgr struct {
|
||||
emit _emit
|
||||
}
|
||||
|
||||
type DbgFunction func(values ...interface{})
|
||||
|
||||
func NewDbgr() *Dbgr {
|
||||
self := &Dbgr{}
|
||||
return self
|
||||
}
|
||||
|
||||
/*
|
||||
New will create and return a pair of debugging functions. You can customize where
|
||||
they output to by passing in an (optional) customization function:
|
||||
|
||||
import (
|
||||
Dbg "github.com/robertkrimen/dbg"
|
||||
"os"
|
||||
)
|
||||
|
||||
# dbg to os.Stderr
|
||||
dbg, dbgf := Dbg.New(func(dbgr *Dbgr) {
|
||||
dbgr.SetOutput(os.Stderr)
|
||||
})
|
||||
|
||||
*/
|
||||
func New(options ...interface{}) (dbg DbgFunction, dbgf DbgFunction) {
|
||||
dbgr := NewDbgr()
|
||||
if len(options) > 0 {
|
||||
if fn, ok := options[0].(func(*Dbgr)); ok {
|
||||
fn(dbgr)
|
||||
}
|
||||
}
|
||||
return dbgr.DbgDbgf()
|
||||
}
|
||||
|
||||
func (self Dbgr) Dbg(values ...interface{}) {
|
||||
self.getEmit().emit(_frmt{}, "", values...)
|
||||
}
|
||||
|
||||
func (self Dbgr) Dbgf(values ...interface{}) {
|
||||
self.dbgf(values...)
|
||||
}
|
||||
|
||||
func (self Dbgr) DbgDbgf() (dbg DbgFunction, dbgf DbgFunction) {
|
||||
dbg = func(vl ...interface{}) {
|
||||
self.Dbg(vl...)
|
||||
}
|
||||
dbgf = func(vl ...interface{}) {
|
||||
self.dbgf(vl...)
|
||||
}
|
||||
return dbg, dbgf // Redundant, but...
|
||||
}
|
||||
|
||||
func (self Dbgr) dbgf(values ...interface{}) {
|
||||
|
||||
var frmt _frmt
|
||||
if len(values) > 0 {
|
||||
tmp := fmt.Sprint(values[0])
|
||||
frmt = parseFormat(tmp)
|
||||
values = values[1:]
|
||||
}
|
||||
|
||||
buffer_f := bytes.Buffer{}
|
||||
format := frmt.format
|
||||
end := len(format)
|
||||
for at := 0; at < end; {
|
||||
last := at
|
||||
for at < end && format[at] != '%' {
|
||||
at++
|
||||
}
|
||||
if at > last {
|
||||
buffer_f.WriteString(format[last:at])
|
||||
}
|
||||
if at >= end {
|
||||
break
|
||||
}
|
||||
// format[at] == '%'
|
||||
at++
|
||||
// format[at] == ?
|
||||
if format[at] == '@' {
|
||||
depth := 2
|
||||
pc, _, _, _ := runtime.Caller(depth)
|
||||
name := runtime.FuncForPC(pc).Name()
|
||||
buffer_f.WriteString(name)
|
||||
} else {
|
||||
buffer_f.WriteString(format[at-1 : at+1])
|
||||
}
|
||||
at++
|
||||
}
|
||||
|
||||
//values_f := append([]interface{}{}, values[0:frmt.operandCount]...)
|
||||
values_f := values[0:frmt.operandCount]
|
||||
values_dbg := values[frmt.operandCount:]
|
||||
if len(values_dbg) > 0 {
|
||||
// Adjust frmt.format:
|
||||
// (%v instead of %s because: frmt.check)
|
||||
{
|
||||
tmp := format
|
||||
if len(tmp) > 0 {
|
||||
if unicode.IsSpace(rune(tmp[len(tmp)-1])) {
|
||||
buffer_f.WriteString("%v")
|
||||
} else {
|
||||
buffer_f.WriteString(" %v")
|
||||
}
|
||||
} else if frmt.check {
|
||||
// Performing a check, so no output
|
||||
} else {
|
||||
buffer_f.WriteString("%v")
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust values_f:
|
||||
if !frmt.check {
|
||||
tmp := []string{}
|
||||
for _, value := range values_dbg {
|
||||
tmp = append(tmp, fmt.Sprintf("%v", value))
|
||||
}
|
||||
// First, make a copy of values_f, so we avoid overwriting values_dbg when appending
|
||||
values_f = append([]interface{}{}, values_f...)
|
||||
values_f = append(values_f, strings.Join(tmp, " "))
|
||||
}
|
||||
}
|
||||
|
||||
format = buffer_f.String()
|
||||
if frmt.check {
|
||||
// We do not actually emit to the log, but panic if
|
||||
// a non-nil value is detected (e.g. a non-nil error)
|
||||
for _, value := range values_dbg {
|
||||
if value != nil {
|
||||
if format == "" {
|
||||
panic(value)
|
||||
} else {
|
||||
panic(fmt.Sprintf(format, append(values_f, value)...))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.getEmit().emit(frmt, format, values_f...)
|
||||
}
|
||||
}
|
||||
|
||||
// Idiot-proof &Dbgr{}, etc.
|
||||
func (self *Dbgr) getEmit() _emit {
|
||||
if self.emit == nil {
|
||||
self.emit = standardEmit()
|
||||
}
|
||||
return self.emit
|
||||
}
|
||||
|
||||
// SetOutput will accept the following as a destination for output:
|
||||
//
|
||||
// *log.Logger Print*/Panic*/Fatal* of the logger
|
||||
// io.Writer -
|
||||
// nil Reset to the default output (os.Stderr)
|
||||
// "log" Print*/Panic*/Fatal* via the "log" package
|
||||
//
|
||||
func (self *Dbgr) SetOutput(output interface{}) {
|
||||
if output == nil {
|
||||
self.emit = standardEmit()
|
||||
return
|
||||
}
|
||||
switch output := output.(type) {
|
||||
case *log.Logger:
|
||||
self.emit = _emitLogger{
|
||||
logger: output,
|
||||
}
|
||||
return
|
||||
case io.Writer:
|
||||
self.emit = _emitWriter{
|
||||
writer: output,
|
||||
}
|
||||
return
|
||||
case string:
|
||||
if output == "log" {
|
||||
self.emit = _emitLog{}
|
||||
return
|
||||
}
|
||||
}
|
||||
panic(output)
|
||||
}
|
||||
|
||||
// ======== //
|
||||
// = emit = //
|
||||
// ======== //
|
||||
|
||||
func standardEmit() _emit {
|
||||
return _emitWriter{
|
||||
writer: os.Stderr,
|
||||
}
|
||||
}
|
||||
|
||||
func ln(tmp string) string {
|
||||
length := len(tmp)
|
||||
if length > 0 && tmp[length-1] != '\n' {
|
||||
return tmp + "\n"
|
||||
}
|
||||
return tmp
|
||||
}
|
||||
|
||||
type _emit interface {
|
||||
emit(_frmt, string, ...interface{})
|
||||
}
|
||||
|
||||
type _emitWriter struct {
|
||||
writer io.Writer
|
||||
}
|
||||
|
||||
func (self _emitWriter) emit(frmt _frmt, format string, values ...interface{}) {
|
||||
if format == "" {
|
||||
fmt.Fprintln(self.writer, values...)
|
||||
} else {
|
||||
if frmt.panic {
|
||||
panic(fmt.Sprintf(format, values...))
|
||||
}
|
||||
fmt.Fprintf(self.writer, ln(format), values...)
|
||||
if frmt.fatal {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type _emitLogger struct {
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
func (self _emitLogger) emit(frmt _frmt, format string, values ...interface{}) {
|
||||
if format == "" {
|
||||
self.logger.Println(values...)
|
||||
} else {
|
||||
if frmt.panic {
|
||||
self.logger.Panicf(format, values...)
|
||||
} else if frmt.fatal {
|
||||
self.logger.Fatalf(format, values...)
|
||||
} else {
|
||||
self.logger.Printf(format, values...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type _emitLog struct {
|
||||
}
|
||||
|
||||
func (self _emitLog) emit(frmt _frmt, format string, values ...interface{}) {
|
||||
if format == "" {
|
||||
log.Println(values...)
|
||||
} else {
|
||||
if frmt.panic {
|
||||
log.Panicf(format, values...)
|
||||
} else if frmt.fatal {
|
||||
log.Fatalf(format, values...)
|
||||
} else {
|
||||
log.Printf(format, values...)
|
||||
}
|
||||
}
|
||||
}
|
||||
280
Godeps/_workspace/src/github.com/obscuren/otto/environment.go
generated
vendored
280
Godeps/_workspace/src/github.com/obscuren/otto/environment.go
generated
vendored
|
|
@ -1,280 +0,0 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// _environment
|
||||
|
||||
type _environment interface {
|
||||
HasBinding(string) bool
|
||||
|
||||
CreateMutableBinding(string, bool)
|
||||
SetMutableBinding(string, Value, bool)
|
||||
// SetMutableBinding with Lazy CreateMutableBinding(..., true)
|
||||
SetValue(string, Value, bool)
|
||||
|
||||
GetBindingValue(string, bool) Value
|
||||
GetValue(string, bool) Value // GetBindingValue
|
||||
DeleteBinding(string) bool
|
||||
ImplicitThisValue() *_object
|
||||
|
||||
Outer() _environment
|
||||
|
||||
newReference(string, bool) _reference
|
||||
clone(clone *_clone) _environment
|
||||
runtimeOf() *_runtime
|
||||
}
|
||||
|
||||
// _functionEnvironment
|
||||
|
||||
type _functionEnvironment struct {
|
||||
_declarativeEnvironment
|
||||
arguments *_object
|
||||
indexOfArgumentName map[string]string
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newFunctionEnvironment(outer _environment) *_functionEnvironment {
|
||||
return &_functionEnvironment{
|
||||
_declarativeEnvironment: _declarativeEnvironment{
|
||||
runtime: runtime,
|
||||
outer: outer,
|
||||
property: map[string]_declarativeProperty{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self0 _functionEnvironment) clone(clone *_clone) _environment {
|
||||
return &_functionEnvironment{
|
||||
*(self0._declarativeEnvironment.clone(clone).(*_declarativeEnvironment)),
|
||||
clone.object(self0.arguments),
|
||||
self0.indexOfArgumentName,
|
||||
}
|
||||
}
|
||||
|
||||
func (self _functionEnvironment) runtimeOf() *_runtime {
|
||||
return self._declarativeEnvironment.runtimeOf()
|
||||
}
|
||||
|
||||
// _objectEnvironment
|
||||
|
||||
type _objectEnvironment struct {
|
||||
runtime *_runtime
|
||||
outer _environment
|
||||
Object *_object
|
||||
ProvideThis bool
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) runtimeOf() *_runtime {
|
||||
return self.runtime
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newObjectEnvironment(object *_object, outer _environment) *_objectEnvironment {
|
||||
if object == nil {
|
||||
object = runtime.newBaseObject()
|
||||
object.class = "environment"
|
||||
}
|
||||
return &_objectEnvironment{
|
||||
runtime: runtime,
|
||||
outer: outer,
|
||||
Object: object,
|
||||
}
|
||||
}
|
||||
|
||||
func (self0 *_objectEnvironment) clone(clone *_clone) _environment {
|
||||
self1, exists := clone.objectEnvironment(self0)
|
||||
if exists {
|
||||
return self1
|
||||
}
|
||||
*self1 = _objectEnvironment{
|
||||
clone.runtime,
|
||||
clone.environment(self0.outer),
|
||||
clone.object(self0.Object),
|
||||
self0.ProvideThis,
|
||||
}
|
||||
return self1
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) HasBinding(name string) bool {
|
||||
return self.Object.hasProperty(name)
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) CreateMutableBinding(name string, deletable bool) {
|
||||
if self.Object.hasProperty(name) {
|
||||
panic(hereBeDragons())
|
||||
}
|
||||
mode := _propertyMode(0111)
|
||||
if !deletable {
|
||||
mode = _propertyMode(0110)
|
||||
}
|
||||
// TODO False?
|
||||
self.Object.defineProperty(name, UndefinedValue(), mode, false)
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) SetMutableBinding(name string, value Value, strict bool) {
|
||||
self.Object.put(name, value, strict)
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) SetValue(name string, value Value, throw bool) {
|
||||
if !self.HasBinding(name) {
|
||||
self.CreateMutableBinding(name, true) // Configurable by default
|
||||
}
|
||||
self.SetMutableBinding(name, value, throw)
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) GetBindingValue(name string, strict bool) Value {
|
||||
if self.Object.hasProperty(name) {
|
||||
return self.Object.get(name)
|
||||
}
|
||||
if strict {
|
||||
panic(newReferenceError("Not Defined", name))
|
||||
}
|
||||
return UndefinedValue()
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) GetValue(name string, throw bool) Value {
|
||||
return self.GetBindingValue(name, throw)
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) DeleteBinding(name string) bool {
|
||||
return self.Object.delete(name, false)
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) ImplicitThisValue() *_object {
|
||||
if self.ProvideThis {
|
||||
return self.Object
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) Outer() _environment {
|
||||
return self.outer
|
||||
}
|
||||
|
||||
func (self *_objectEnvironment) newReference(name string, strict bool) _reference {
|
||||
return newPropertyReference(self.Object, name, strict)
|
||||
}
|
||||
|
||||
// _declarativeEnvironment
|
||||
|
||||
func (runtime *_runtime) newDeclarativeEnvironment(outer _environment) *_declarativeEnvironment {
|
||||
return &_declarativeEnvironment{
|
||||
runtime: runtime,
|
||||
outer: outer,
|
||||
property: map[string]_declarativeProperty{},
|
||||
}
|
||||
}
|
||||
|
||||
func (self0 *_declarativeEnvironment) clone(clone *_clone) _environment {
|
||||
self1, exists := clone.declarativeEnvironment(self0)
|
||||
if exists {
|
||||
return self1
|
||||
}
|
||||
property := make(map[string]_declarativeProperty, len(self0.property))
|
||||
for index, value := range self0.property {
|
||||
property[index] = clone.declarativeProperty(value)
|
||||
}
|
||||
*self1 = _declarativeEnvironment{
|
||||
clone.runtime,
|
||||
clone.environment(self0.outer),
|
||||
property,
|
||||
}
|
||||
return self1
|
||||
}
|
||||
|
||||
type _declarativeProperty struct {
|
||||
value Value
|
||||
mutable bool
|
||||
deletable bool
|
||||
readable bool
|
||||
}
|
||||
|
||||
type _declarativeEnvironment struct {
|
||||
runtime *_runtime
|
||||
outer _environment
|
||||
property map[string]_declarativeProperty
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) HasBinding(name string) bool {
|
||||
_, exists := self.property[name]
|
||||
return exists
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) runtimeOf() *_runtime {
|
||||
return self.runtime
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) CreateMutableBinding(name string, deletable bool) {
|
||||
_, exists := self.property[name]
|
||||
if exists {
|
||||
panic(fmt.Errorf("CreateMutableBinding: %s: already exists", name))
|
||||
}
|
||||
self.property[name] = _declarativeProperty{
|
||||
value: UndefinedValue(),
|
||||
mutable: true,
|
||||
deletable: deletable,
|
||||
readable: false,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) SetMutableBinding(name string, value Value, strict bool) {
|
||||
property, exists := self.property[name]
|
||||
if !exists {
|
||||
panic(fmt.Errorf("SetMutableBinding: %s: missing", name))
|
||||
}
|
||||
if property.mutable {
|
||||
property.value = value
|
||||
self.property[name] = property
|
||||
} else {
|
||||
typeErrorResult(strict)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) SetValue(name string, value Value, throw bool) {
|
||||
if !self.HasBinding(name) {
|
||||
self.CreateMutableBinding(name, false) // NOT deletable by default
|
||||
}
|
||||
self.SetMutableBinding(name, value, throw)
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) GetBindingValue(name string, strict bool) Value {
|
||||
property, exists := self.property[name]
|
||||
if !exists {
|
||||
panic(fmt.Errorf("GetBindingValue: %s: missing", name))
|
||||
}
|
||||
if !property.mutable && !property.readable {
|
||||
if strict {
|
||||
panic(newTypeError())
|
||||
}
|
||||
return UndefinedValue()
|
||||
}
|
||||
return property.value
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) GetValue(name string, throw bool) Value {
|
||||
return self.GetBindingValue(name, throw)
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) DeleteBinding(name string) bool {
|
||||
property, exists := self.property[name]
|
||||
if !exists {
|
||||
return true
|
||||
}
|
||||
if !property.deletable {
|
||||
return false
|
||||
}
|
||||
delete(self.property, name)
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) ImplicitThisValue() *_object {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) Outer() _environment {
|
||||
return self.outer
|
||||
}
|
||||
|
||||
func (self *_declarativeEnvironment) newReference(name string, strict bool) _reference {
|
||||
return newEnvironmentReference(self, name, strict, nil)
|
||||
}
|
||||
152
Godeps/_workspace/src/github.com/obscuren/otto/error.go
generated
vendored
152
Godeps/_workspace/src/github.com/obscuren/otto/error.go
generated
vendored
|
|
@ -1,152 +0,0 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
)
|
||||
|
||||
type _exception struct {
|
||||
value interface{}
|
||||
}
|
||||
|
||||
func newException(value interface{}) *_exception {
|
||||
return &_exception{
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_exception) eject() interface{} {
|
||||
value := self.value
|
||||
self.value = nil // Prevent Go from holding on to the value, whatever it is
|
||||
return value
|
||||
}
|
||||
|
||||
type _error struct {
|
||||
Name string
|
||||
Message string
|
||||
|
||||
Line int // Hackish -- line where the error/exception occurred
|
||||
}
|
||||
|
||||
var messageDetail map[string]string = map[string]string{
|
||||
"notDefined": "%v is not defined",
|
||||
}
|
||||
|
||||
func messageFromDescription(description string, argumentList ...interface{}) string {
|
||||
message := messageDetail[description]
|
||||
if message == "" {
|
||||
message = description
|
||||
}
|
||||
message = fmt.Sprintf(message, argumentList...)
|
||||
return message
|
||||
}
|
||||
|
||||
func (self _error) MessageValue() Value {
|
||||
if self.Message == "" {
|
||||
return UndefinedValue()
|
||||
}
|
||||
return toValue_string(self.Message)
|
||||
}
|
||||
|
||||
func (self _error) String() string {
|
||||
if len(self.Name) == 0 {
|
||||
return self.Message
|
||||
}
|
||||
if len(self.Message) == 0 {
|
||||
return self.Name
|
||||
}
|
||||
return fmt.Sprintf("%s: %s", self.Name, self.Message)
|
||||
}
|
||||
|
||||
func newError(name string, argumentList ...interface{}) _error {
|
||||
description := ""
|
||||
var node ast.Node = nil
|
||||
length := len(argumentList)
|
||||
if length > 0 {
|
||||
if node, _ = argumentList[length-1].(ast.Node); node != nil || argumentList[length-1] == nil {
|
||||
argumentList = argumentList[0 : length-1]
|
||||
length -= 1
|
||||
}
|
||||
if length > 0 {
|
||||
description, argumentList = argumentList[0].(string), argumentList[1:]
|
||||
}
|
||||
}
|
||||
return _error{
|
||||
Name: name,
|
||||
Message: messageFromDescription(description, argumentList...),
|
||||
Line: -1,
|
||||
}
|
||||
//error := _error{
|
||||
// Name: name,
|
||||
// Message: messageFromDescription(description, argumentList...),
|
||||
// Line: -1,
|
||||
//}
|
||||
//if node != nil {
|
||||
// error.Line = ast.position()
|
||||
//}
|
||||
//return error
|
||||
}
|
||||
|
||||
func newReferenceError(argumentList ...interface{}) _error {
|
||||
return newError("ReferenceError", argumentList...)
|
||||
}
|
||||
|
||||
func newTypeError(argumentList ...interface{}) _error {
|
||||
return newError("TypeError", argumentList...)
|
||||
}
|
||||
|
||||
func newRangeError(argumentList ...interface{}) _error {
|
||||
return newError("RangeError", argumentList...)
|
||||
}
|
||||
|
||||
func newSyntaxError(argumentList ...interface{}) _error {
|
||||
return newError("SyntaxError", argumentList...)
|
||||
}
|
||||
|
||||
func newURIError(argumentList ...interface{}) _error {
|
||||
return newError("URIError", argumentList...)
|
||||
}
|
||||
|
||||
func typeErrorResult(throw bool) bool {
|
||||
if throw {
|
||||
panic(newTypeError())
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func catchPanic(function func()) (err error) {
|
||||
// FIXME
|
||||
defer func() {
|
||||
if caught := recover(); caught != nil {
|
||||
if exception, ok := caught.(*_exception); ok {
|
||||
caught = exception.eject()
|
||||
}
|
||||
switch caught := caught.(type) {
|
||||
//case *_syntaxError:
|
||||
// err = errors.New(fmt.Sprintf("%s (line %d)", caught.String(), caught.Line+0))
|
||||
// return
|
||||
case _error:
|
||||
if caught.Line == -1 {
|
||||
err = errors.New(caught.String())
|
||||
} else {
|
||||
// We're 0-based (for now), hence the + 1
|
||||
err = errors.New(fmt.Sprintf("%s (line %d)", caught.String(), caught.Line+1))
|
||||
}
|
||||
return
|
||||
case Value:
|
||||
err = errors.New(toString(caught))
|
||||
return
|
||||
//case string:
|
||||
// if strings.HasPrefix(caught, "SyntaxError:") {
|
||||
// err = errors.New(caught)
|
||||
// return
|
||||
// }
|
||||
}
|
||||
panic(caught)
|
||||
}
|
||||
}()
|
||||
function()
|
||||
return nil
|
||||
}
|
||||
62
Godeps/_workspace/src/github.com/obscuren/otto/error_test.go
generated
vendored
62
Godeps/_workspace/src/github.com/obscuren/otto/error_test.go
generated
vendored
|
|
@ -1,62 +0,0 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestError(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`
|
||||
[ Error.prototype.name, Error.prototype.message, Error.prototype.hasOwnProperty("message") ];
|
||||
`, "Error,,true")
|
||||
})
|
||||
}
|
||||
|
||||
func TestError_instanceof(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`(new TypeError()) instanceof Error`, true)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPanicValue(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
vm.Set("abc", func(call FunctionCall) Value {
|
||||
value, err := call.Otto.Run(`({ def: 3.14159 })`)
|
||||
is(err, nil)
|
||||
panic(value)
|
||||
})
|
||||
|
||||
test(`
|
||||
try {
|
||||
abc();
|
||||
}
|
||||
catch (err) {
|
||||
error = err;
|
||||
}
|
||||
[ error instanceof Error, error.message, error.def ];
|
||||
`, "false,,3.14159")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_catchPanic(t *testing.T) {
|
||||
tt(t, func() {
|
||||
vm := New()
|
||||
|
||||
_, err := vm.Run(`
|
||||
A syntax error that
|
||||
does not define
|
||||
var;
|
||||
abc;
|
||||
`)
|
||||
is(err, "!=", nil)
|
||||
|
||||
_, err = vm.Call(`abc.def`, nil)
|
||||
is(err, "!=", nil)
|
||||
})
|
||||
}
|
||||
40
Godeps/_workspace/src/github.com/obscuren/otto/execution_context.go
generated
vendored
40
Godeps/_workspace/src/github.com/obscuren/otto/execution_context.go
generated
vendored
|
|
@ -1,40 +0,0 @@
|
|||
package otto
|
||||
|
||||
type _executionContext struct {
|
||||
LexicalEnvironment _environment
|
||||
VariableEnvironment _environment
|
||||
this *_object
|
||||
eval bool // Replace this with kind?
|
||||
}
|
||||
|
||||
func newExecutionContext(lexical _environment, variable _environment, this *_object) *_executionContext {
|
||||
return &_executionContext{
|
||||
LexicalEnvironment: lexical,
|
||||
VariableEnvironment: variable,
|
||||
this: this,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_executionContext) getValue(name string) Value {
|
||||
strict := false
|
||||
return self.LexicalEnvironment.GetValue(name, strict)
|
||||
}
|
||||
|
||||
func (self *_executionContext) setValue(name string, value Value, throw bool) {
|
||||
self.LexicalEnvironment.SetValue(name, value, throw)
|
||||
}
|
||||
|
||||
func (self *_executionContext) newLexicalEnvironment(object *_object) (_environment, *_objectEnvironment) {
|
||||
// Get runtime from the object (for now)
|
||||
runtime := object.runtime
|
||||
previousLexical := self.LexicalEnvironment
|
||||
newLexical := runtime.newObjectEnvironment(object, self.LexicalEnvironment)
|
||||
self.LexicalEnvironment = newLexical
|
||||
return previousLexical, newLexical
|
||||
}
|
||||
|
||||
func (self *_executionContext) newDeclarativeEnvironment(runtime *_runtime) _environment {
|
||||
previousLexical := self.LexicalEnvironment
|
||||
self.LexicalEnvironment = runtime.newDeclarativeEnvironment(self.LexicalEnvironment)
|
||||
return previousLexical
|
||||
}
|
||||
72
Godeps/_workspace/src/github.com/obscuren/otto/file/README.markdown
generated
vendored
72
Godeps/_workspace/src/github.com/obscuren/otto/file/README.markdown
generated
vendored
|
|
@ -1,72 +0,0 @@
|
|||
# file
|
||||
--
|
||||
import "github.com/robertkrimen/otto/file"
|
||||
|
||||
Package file encapsulates the file abstractions used by the ast & parser.
|
||||
|
||||
## Usage
|
||||
|
||||
#### type FileSet
|
||||
|
||||
```go
|
||||
type FileSet struct {
|
||||
}
|
||||
```
|
||||
|
||||
A FileSet represents a set of source files.
|
||||
|
||||
#### func (*FileSet) AddFile
|
||||
|
||||
```go
|
||||
func (self *FileSet) AddFile(filename, src string) int
|
||||
```
|
||||
AddFile adds a new file with the given filename and src.
|
||||
|
||||
This an internal method, but exported for cross-package use.
|
||||
|
||||
#### func (*FileSet) Position
|
||||
|
||||
```go
|
||||
func (self *FileSet) Position(idx Idx) *Position
|
||||
```
|
||||
Position converts an Idx in the FileSet into a Position.
|
||||
|
||||
#### type Idx
|
||||
|
||||
```go
|
||||
type Idx int
|
||||
```
|
||||
|
||||
Idx is a compact encoding of a source position within a file set. It can be
|
||||
converted into a Position for a more convenient, but much larger,
|
||||
representation.
|
||||
|
||||
#### type Position
|
||||
|
||||
```go
|
||||
type Position struct {
|
||||
Filename string // The filename where the error occurred, if any
|
||||
Offset int // The src offset
|
||||
Line int // The line number, starting at 1
|
||||
Column int // The column number, starting at 1 (The character count)
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Position describes an arbitrary source position including the filename, line,
|
||||
and column location.
|
||||
|
||||
#### func (*Position) String
|
||||
|
||||
```go
|
||||
func (self *Position) String() string
|
||||
```
|
||||
String returns a string in one of several forms:
|
||||
|
||||
file:line:column A valid position with filename
|
||||
line:column A valid position without filename
|
||||
file An invalid position with filename
|
||||
- An invalid position without filename
|
||||
|
||||
--
|
||||
**godocdown** http://github.com/robertkrimen/godocdown
|
||||
106
Godeps/_workspace/src/github.com/obscuren/otto/file/file.go
generated
vendored
106
Godeps/_workspace/src/github.com/obscuren/otto/file/file.go
generated
vendored
|
|
@ -1,106 +0,0 @@
|
|||
// Package file encapsulates the file abstractions used by the ast & parser.
|
||||
//
|
||||
package file
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Idx is a compact encoding of a source position within a file set.
|
||||
// It can be converted into a Position for a more convenient, but much
|
||||
// larger, representation.
|
||||
type Idx int
|
||||
|
||||
// Position describes an arbitrary source position
|
||||
// including the filename, line, and column location.
|
||||
type Position struct {
|
||||
Filename string // The filename where the error occurred, if any
|
||||
Offset int // The src offset
|
||||
Line int // The line number, starting at 1
|
||||
Column int // The column number, starting at 1 (The character count)
|
||||
|
||||
}
|
||||
|
||||
// A Position is valid if the line number is > 0.
|
||||
|
||||
func (self *Position) isValid() bool {
|
||||
return self.Line > 0
|
||||
}
|
||||
|
||||
// String returns a string in one of several forms:
|
||||
//
|
||||
// file:line:column A valid position with filename
|
||||
// line:column A valid position without filename
|
||||
// file An invalid position with filename
|
||||
// - An invalid position without filename
|
||||
//
|
||||
func (self *Position) String() string {
|
||||
str := self.Filename
|
||||
if self.isValid() {
|
||||
if str != "" {
|
||||
str += ":"
|
||||
}
|
||||
str += fmt.Sprintf("%d:%d", self.Line, self.Column)
|
||||
}
|
||||
if str == "" {
|
||||
str = "-"
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
// FileSet
|
||||
|
||||
// A FileSet represents a set of source files.
|
||||
type FileSet struct {
|
||||
files []*_file
|
||||
last *_file
|
||||
}
|
||||
|
||||
// AddFile adds a new file with the given filename and src.
|
||||
//
|
||||
// This an internal method, but exported for cross-package use.
|
||||
func (self *FileSet) AddFile(filename, src string) int {
|
||||
base := self.nextBase()
|
||||
file := &_file{
|
||||
filename: filename,
|
||||
src: src,
|
||||
base: base,
|
||||
}
|
||||
self.files = append(self.files, file)
|
||||
self.last = file
|
||||
return base
|
||||
}
|
||||
|
||||
func (self *FileSet) nextBase() int {
|
||||
if self.last == nil {
|
||||
return 1
|
||||
}
|
||||
return self.last.base + len(self.last.src) + 1
|
||||
}
|
||||
|
||||
// Position converts an Idx in the FileSet into a Position.
|
||||
func (self *FileSet) Position(idx Idx) *Position {
|
||||
position := &Position{}
|
||||
for _, file := range self.files {
|
||||
if idx <= Idx(file.base+len(file.src)) {
|
||||
offset := int(idx) - file.base
|
||||
src := file.src[:offset]
|
||||
position.Filename = file.filename
|
||||
position.Offset = offset
|
||||
position.Line = 1 + strings.Count(src, "\n")
|
||||
if index := strings.LastIndex(src, "\n"); index >= 0 {
|
||||
position.Column = offset - index
|
||||
} else {
|
||||
position.Column = 1 + len(src)
|
||||
}
|
||||
}
|
||||
}
|
||||
return position
|
||||
}
|
||||
|
||||
type _file struct {
|
||||
filename string
|
||||
src string
|
||||
base int // This will always be 1 or greater
|
||||
}
|
||||
4
Godeps/_workspace/src/github.com/obscuren/otto/parser/Makefile
generated
vendored
4
Godeps/_workspace/src/github.com/obscuren/otto/parser/Makefile
generated
vendored
|
|
@ -1,4 +0,0 @@
|
|||
.PHONY: test
|
||||
|
||||
test:
|
||||
go test
|
||||
190
Godeps/_workspace/src/github.com/obscuren/otto/parser/README.markdown
generated
vendored
190
Godeps/_workspace/src/github.com/obscuren/otto/parser/README.markdown
generated
vendored
|
|
@ -1,190 +0,0 @@
|
|||
# parser
|
||||
--
|
||||
import "github.com/robertkrimen/otto/parser"
|
||||
|
||||
Package parser implements a parser for JavaScript.
|
||||
|
||||
import (
|
||||
"github.com/robertkrimen/otto/parser"
|
||||
)
|
||||
|
||||
Parse and return an AST
|
||||
|
||||
filename := "" // A filename is optional
|
||||
src := `
|
||||
// Sample xyzzy example
|
||||
(function(){
|
||||
if (3.14159 > 0) {
|
||||
console.log("Hello, World.");
|
||||
return;
|
||||
}
|
||||
|
||||
var xyzzy = NaN;
|
||||
console.log("Nothing happens.");
|
||||
return xyzzy;
|
||||
})();
|
||||
`
|
||||
|
||||
// Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
|
||||
program, err := parser.ParseFile(nil, filename, src, 0)
|
||||
|
||||
|
||||
### Warning
|
||||
|
||||
The parser and AST interfaces are still works-in-progress (particularly where
|
||||
node types are concerned) and may change in the future.
|
||||
|
||||
## Usage
|
||||
|
||||
#### func ParseFile
|
||||
|
||||
```go
|
||||
func ParseFile(fileSet *file.FileSet, filename string, src interface{}, mode Mode) (*ast.Program, error)
|
||||
```
|
||||
ParseFile parses the source code of a single JavaScript/ECMAScript source file
|
||||
and returns the corresponding ast.Program node.
|
||||
|
||||
If fileSet == nil, ParseFile parses source without a FileSet. If fileSet != nil,
|
||||
ParseFile first adds filename and src to fileSet.
|
||||
|
||||
The filename argument is optional and is used for labelling errors, etc.
|
||||
|
||||
src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST
|
||||
always be in UTF-8.
|
||||
|
||||
// Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
|
||||
program, err := parser.ParseFile(nil, "", `if (abc > 1) {}`, 0)
|
||||
|
||||
#### func ParseFunction
|
||||
|
||||
```go
|
||||
func ParseFunction(parameterList, body string) (*ast.FunctionLiteral, error)
|
||||
```
|
||||
ParseFunction parses a given parameter list and body as a function and returns
|
||||
the corresponding ast.FunctionLiteral node.
|
||||
|
||||
The parameter list, if any, should be a comma-separated list of identifiers.
|
||||
|
||||
#### func ReadSource
|
||||
|
||||
```go
|
||||
func ReadSource(filename string, src interface{}) ([]byte, error)
|
||||
```
|
||||
|
||||
#### func TransformRegExp
|
||||
|
||||
```go
|
||||
func TransformRegExp(pattern string) (string, error)
|
||||
```
|
||||
TransformRegExp transforms a JavaScript pattern into a Go "regexp" pattern.
|
||||
|
||||
re2 (Go) cannot do backtracking, so the presence of a lookahead (?=) (?!) or
|
||||
backreference (\1, \2, ...) will cause an error.
|
||||
|
||||
re2 (Go) has a different definition for \s: [\t\n\f\r ]. The JavaScript
|
||||
definition, on the other hand, also includes \v, Unicode "Separator, Space",
|
||||
etc.
|
||||
|
||||
If the pattern is invalid (not valid even in JavaScript), then this function
|
||||
returns the empty string and an error.
|
||||
|
||||
If the pattern is valid, but incompatible (contains a lookahead or
|
||||
backreference), then this function returns the transformation (a non-empty
|
||||
string) AND an error.
|
||||
|
||||
#### type Error
|
||||
|
||||
```go
|
||||
type Error struct {
|
||||
Position file.Position
|
||||
Message string
|
||||
}
|
||||
```
|
||||
|
||||
An Error represents a parsing error. It includes the position where the error
|
||||
occurred and a message/description.
|
||||
|
||||
#### func (Error) Error
|
||||
|
||||
```go
|
||||
func (self Error) Error() string
|
||||
```
|
||||
|
||||
#### type ErrorList
|
||||
|
||||
```go
|
||||
type ErrorList []*Error
|
||||
```
|
||||
|
||||
ErrorList is a list of *Errors.
|
||||
|
||||
#### func (*ErrorList) Add
|
||||
|
||||
```go
|
||||
func (self *ErrorList) Add(position file.Position, msg string)
|
||||
```
|
||||
Add adds an Error with given position and message to an ErrorList.
|
||||
|
||||
#### func (ErrorList) Err
|
||||
|
||||
```go
|
||||
func (self ErrorList) Err() error
|
||||
```
|
||||
Err returns an error equivalent to this ErrorList. If the list is empty, Err
|
||||
returns nil.
|
||||
|
||||
#### func (ErrorList) Error
|
||||
|
||||
```go
|
||||
func (self ErrorList) Error() string
|
||||
```
|
||||
Error implements the Error interface.
|
||||
|
||||
#### func (ErrorList) Len
|
||||
|
||||
```go
|
||||
func (self ErrorList) Len() int
|
||||
```
|
||||
|
||||
#### func (ErrorList) Less
|
||||
|
||||
```go
|
||||
func (self ErrorList) Less(i, j int) bool
|
||||
```
|
||||
|
||||
#### func (*ErrorList) Reset
|
||||
|
||||
```go
|
||||
func (self *ErrorList) Reset()
|
||||
```
|
||||
Reset resets an ErrorList to no errors.
|
||||
|
||||
#### func (ErrorList) Sort
|
||||
|
||||
```go
|
||||
func (self ErrorList) Sort()
|
||||
```
|
||||
|
||||
#### func (ErrorList) Swap
|
||||
|
||||
```go
|
||||
func (self ErrorList) Swap(i, j int)
|
||||
```
|
||||
|
||||
#### type Mode
|
||||
|
||||
```go
|
||||
type Mode uint
|
||||
```
|
||||
|
||||
A Mode value is a set of flags (or 0). They control optional parser
|
||||
functionality.
|
||||
|
||||
```go
|
||||
const (
|
||||
IgnoreRegExpErrors Mode = 1 << iota // Ignore RegExp compatibility errors (allow backtracking)
|
||||
)
|
||||
```
|
||||
|
||||
--
|
||||
**godocdown** http://github.com/robertkrimen/godocdown
|
||||
9
Godeps/_workspace/src/github.com/obscuren/otto/parser/dbg.go
generated
vendored
9
Godeps/_workspace/src/github.com/obscuren/otto/parser/dbg.go
generated
vendored
|
|
@ -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()
|
||||
175
Godeps/_workspace/src/github.com/obscuren/otto/parser/error.go
generated
vendored
175
Godeps/_workspace/src/github.com/obscuren/otto/parser/error.go
generated
vendored
|
|
@ -1,175 +0,0 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/robertkrimen/otto/file"
|
||||
"github.com/robertkrimen/otto/token"
|
||||
)
|
||||
|
||||
const (
|
||||
err_UnexpectedToken = "Unexpected token %v"
|
||||
err_UnexpectedEndOfInput = "Unexpected end of input"
|
||||
err_UnexpectedEscape = "Unexpected escape"
|
||||
)
|
||||
|
||||
// UnexpectedNumber: 'Unexpected number',
|
||||
// UnexpectedString: 'Unexpected string',
|
||||
// UnexpectedIdentifier: 'Unexpected identifier',
|
||||
// UnexpectedReserved: 'Unexpected reserved word',
|
||||
// NewlineAfterThrow: 'Illegal newline after throw',
|
||||
// InvalidRegExp: 'Invalid regular expression',
|
||||
// UnterminatedRegExp: 'Invalid regular expression: missing /',
|
||||
// InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
|
||||
// InvalidLHSInForIn: 'Invalid left-hand side in for-in',
|
||||
// MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
|
||||
// NoCatchOrFinally: 'Missing catch or finally after try',
|
||||
// UnknownLabel: 'Undefined label \'%0\'',
|
||||
// Redeclaration: '%0 \'%1\' has already been declared',
|
||||
// IllegalContinue: 'Illegal continue statement',
|
||||
// IllegalBreak: 'Illegal break statement',
|
||||
// IllegalReturn: 'Illegal return statement',
|
||||
// StrictModeWith: 'Strict mode code may not include a with statement',
|
||||
// StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
|
||||
// StrictVarName: 'Variable name may not be eval or arguments in strict mode',
|
||||
// StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
|
||||
// StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
|
||||
// StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
|
||||
// StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
|
||||
// StrictDelete: 'Delete of an unqualified identifier in strict mode.',
|
||||
// StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',
|
||||
// AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',
|
||||
// AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',
|
||||
// StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
|
||||
// StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
|
||||
// StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
|
||||
// StrictReservedWord: 'Use of future reserved word in strict mode'
|
||||
|
||||
// A SyntaxError is a description of an ECMAScript syntax error.
|
||||
|
||||
// An Error represents a parsing error. It includes the position where the error occurred and a message/description.
|
||||
type Error struct {
|
||||
Position file.Position
|
||||
Message string
|
||||
}
|
||||
|
||||
// FXIME Should this be "SyntaxError"?
|
||||
|
||||
func (self Error) Error() string {
|
||||
filename := self.Position.Filename
|
||||
if filename == "" {
|
||||
filename = "(anonymous)"
|
||||
}
|
||||
return fmt.Sprintf("%s: Line %d:%d %s",
|
||||
filename,
|
||||
self.Position.Line,
|
||||
self.Position.Column,
|
||||
self.Message,
|
||||
)
|
||||
}
|
||||
|
||||
func (self *_parser) error(place interface{}, msg string, msgValues ...interface{}) *Error {
|
||||
idx := file.Idx(0)
|
||||
switch place := place.(type) {
|
||||
case int:
|
||||
idx = self.idxOf(place)
|
||||
case file.Idx:
|
||||
if place == 0 {
|
||||
idx = self.idxOf(self.chrOffset)
|
||||
} else {
|
||||
idx = place
|
||||
}
|
||||
default:
|
||||
panic(fmt.Errorf("error(%T, ...)", place))
|
||||
}
|
||||
|
||||
position := self.position(idx)
|
||||
msg = fmt.Sprintf(msg, msgValues...)
|
||||
self.errors.Add(position, msg)
|
||||
return self.errors[len(self.errors)-1]
|
||||
}
|
||||
|
||||
func (self *_parser) errorUnexpected(idx file.Idx, chr rune) error {
|
||||
if chr == -1 {
|
||||
return self.error(idx, err_UnexpectedEndOfInput)
|
||||
}
|
||||
return self.error(idx, err_UnexpectedToken, token.ILLEGAL)
|
||||
}
|
||||
|
||||
func (self *_parser) errorUnexpectedToken(tkn token.Token) error {
|
||||
switch tkn {
|
||||
case token.EOF:
|
||||
return self.error(file.Idx(0), err_UnexpectedEndOfInput)
|
||||
}
|
||||
value := tkn.String()
|
||||
switch tkn {
|
||||
case token.BOOLEAN, token.NULL:
|
||||
value = self.literal
|
||||
case token.IDENTIFIER:
|
||||
return self.error(self.idx, "Unexpected identifier")
|
||||
case token.KEYWORD:
|
||||
// TODO Might be a future reserved word
|
||||
return self.error(self.idx, "Unexpected reserved word")
|
||||
case token.NUMBER:
|
||||
return self.error(self.idx, "Unexpected number")
|
||||
case token.STRING:
|
||||
return self.error(self.idx, "Unexpected string")
|
||||
}
|
||||
return self.error(self.idx, err_UnexpectedToken, value)
|
||||
}
|
||||
|
||||
// ErrorList is a list of *Errors.
|
||||
//
|
||||
type ErrorList []*Error
|
||||
|
||||
// Add adds an Error with given position and message to an ErrorList.
|
||||
func (self *ErrorList) Add(position file.Position, msg string) {
|
||||
*self = append(*self, &Error{position, msg})
|
||||
}
|
||||
|
||||
// Reset resets an ErrorList to no errors.
|
||||
func (self *ErrorList) Reset() { *self = (*self)[0:0] }
|
||||
|
||||
func (self ErrorList) Len() int { return len(self) }
|
||||
func (self ErrorList) Swap(i, j int) { self[i], self[j] = self[j], self[i] }
|
||||
func (self ErrorList) Less(i, j int) bool {
|
||||
x := &self[i].Position
|
||||
y := &self[j].Position
|
||||
if x.Filename < y.Filename {
|
||||
return true
|
||||
}
|
||||
if x.Filename == y.Filename {
|
||||
if x.Line < y.Line {
|
||||
return true
|
||||
}
|
||||
if x.Line == y.Line {
|
||||
return x.Column < y.Column
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (self ErrorList) Sort() {
|
||||
sort.Sort(self)
|
||||
}
|
||||
|
||||
// Error implements the Error interface.
|
||||
func (self ErrorList) Error() string {
|
||||
switch len(self) {
|
||||
case 0:
|
||||
return "no errors"
|
||||
case 1:
|
||||
return self[0].Error()
|
||||
}
|
||||
return fmt.Sprintf("%s (and %d more errors)", self[0].Error(), len(self)-1)
|
||||
}
|
||||
|
||||
// Err returns an error equivalent to this ErrorList.
|
||||
// If the list is empty, Err returns nil.
|
||||
func (self ErrorList) Err() error {
|
||||
if len(self) == 0 {
|
||||
return nil
|
||||
}
|
||||
return self
|
||||
}
|
||||
815
Godeps/_workspace/src/github.com/obscuren/otto/parser/expression.go
generated
vendored
815
Godeps/_workspace/src/github.com/obscuren/otto/parser/expression.go
generated
vendored
|
|
@ -1,815 +0,0 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
"github.com/robertkrimen/otto/file"
|
||||
"github.com/robertkrimen/otto/token"
|
||||
)
|
||||
|
||||
func (self *_parser) parseIdentifier() *ast.Identifier {
|
||||
literal := self.literal
|
||||
idx := self.idx
|
||||
self.next()
|
||||
return &ast.Identifier{
|
||||
Name: literal,
|
||||
Idx: idx,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parsePrimaryExpression() ast.Expression {
|
||||
literal := self.literal
|
||||
idx := self.idx
|
||||
switch self.token {
|
||||
case token.IDENTIFIER:
|
||||
self.next()
|
||||
if len(literal) > 1 {
|
||||
tkn, strict := token.IsKeyword(literal)
|
||||
if tkn == token.KEYWORD {
|
||||
if !strict {
|
||||
self.error(idx, "Unexpected reserved word")
|
||||
}
|
||||
}
|
||||
}
|
||||
return &ast.Identifier{
|
||||
Name: literal,
|
||||
Idx: idx,
|
||||
}
|
||||
case token.NULL:
|
||||
self.next()
|
||||
return &ast.NullLiteral{
|
||||
Idx: idx,
|
||||
Literal: literal,
|
||||
}
|
||||
case token.BOOLEAN:
|
||||
self.next()
|
||||
value := false
|
||||
switch literal {
|
||||
case "true":
|
||||
value = true
|
||||
case "false":
|
||||
value = false
|
||||
default:
|
||||
self.error(idx, "Illegal boolean literal")
|
||||
}
|
||||
return &ast.BooleanLiteral{
|
||||
Idx: idx,
|
||||
Literal: literal,
|
||||
Value: value,
|
||||
}
|
||||
case token.STRING:
|
||||
self.next()
|
||||
value, err := parseStringLiteral(literal[1 : len(literal)-1])
|
||||
if err != nil {
|
||||
self.error(idx, err.Error())
|
||||
}
|
||||
return &ast.StringLiteral{
|
||||
Idx: idx,
|
||||
Literal: literal,
|
||||
Value: value,
|
||||
}
|
||||
case token.NUMBER:
|
||||
self.next()
|
||||
value, err := parseNumberLiteral(literal)
|
||||
if err != nil {
|
||||
self.error(idx, err.Error())
|
||||
value = 0
|
||||
}
|
||||
return &ast.NumberLiteral{
|
||||
Idx: idx,
|
||||
Literal: literal,
|
||||
Value: value,
|
||||
}
|
||||
case token.SLASH, token.QUOTIENT_ASSIGN:
|
||||
return self.parseRegExpLiteral()
|
||||
case token.LEFT_BRACE:
|
||||
return self.parseObjectLiteral()
|
||||
case token.LEFT_BRACKET:
|
||||
return self.parseArrayLiteral()
|
||||
case token.LEFT_PARENTHESIS:
|
||||
self.expect(token.LEFT_PARENTHESIS)
|
||||
expression := self.parseExpression()
|
||||
self.expect(token.RIGHT_PARENTHESIS)
|
||||
return expression
|
||||
case token.THIS:
|
||||
self.next()
|
||||
return &ast.ThisExpression{
|
||||
Idx: idx,
|
||||
}
|
||||
case token.FUNCTION:
|
||||
return self.parseFunction(false)
|
||||
}
|
||||
|
||||
self.errorUnexpectedToken(self.token)
|
||||
self.nextStatement()
|
||||
return &ast.BadExpression{From: idx, To: self.idx}
|
||||
}
|
||||
|
||||
func (self *_parser) parseRegExpLiteral() *ast.RegExpLiteral {
|
||||
|
||||
offset := self.chrOffset - 1 // Opening slash already gotten
|
||||
if self.token == token.QUOTIENT_ASSIGN {
|
||||
offset -= 1 // =
|
||||
}
|
||||
idx := self.idxOf(offset)
|
||||
|
||||
pattern, err := self.scanString(offset)
|
||||
endOffset := self.chrOffset
|
||||
|
||||
self.next()
|
||||
if err == nil {
|
||||
pattern = pattern[1 : len(pattern)-1]
|
||||
}
|
||||
|
||||
flags := ""
|
||||
if self.token == token.IDENTIFIER { // gim
|
||||
|
||||
flags = self.literal
|
||||
self.next()
|
||||
endOffset = self.chrOffset - 1
|
||||
}
|
||||
|
||||
var value string
|
||||
// TODO 15.10
|
||||
{
|
||||
// Test during parsing that this is a valid regular expression
|
||||
// Sorry, (?=) and (?!) are invalid (for now)
|
||||
pattern, err := TransformRegExp(pattern)
|
||||
if err != nil {
|
||||
if pattern == "" || self.mode&IgnoreRegExpErrors == 0 {
|
||||
self.error(idx, "Invalid regular expression: %s", err.Error())
|
||||
}
|
||||
} else {
|
||||
_, err = regexp.Compile(pattern)
|
||||
if err != nil {
|
||||
// We should not get here, ParseRegExp should catch any errors
|
||||
self.error(idx, "Invalid regular expression: %s", err.Error()[22:]) // Skip redundant "parse regexp error"
|
||||
} else {
|
||||
value = pattern
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
literal := self.str[offset:endOffset]
|
||||
|
||||
return &ast.RegExpLiteral{
|
||||
Idx: idx,
|
||||
Literal: literal,
|
||||
Pattern: pattern,
|
||||
Flags: flags,
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseVariableDeclaration(declarationList *[]*ast.VariableExpression) ast.Expression {
|
||||
|
||||
if self.token != token.IDENTIFIER {
|
||||
idx := self.expect(token.IDENTIFIER)
|
||||
self.nextStatement()
|
||||
return &ast.BadExpression{From: idx, To: self.idx}
|
||||
}
|
||||
|
||||
literal := self.literal
|
||||
idx := self.idx
|
||||
self.next()
|
||||
node := &ast.VariableExpression{
|
||||
Name: literal,
|
||||
Idx: idx,
|
||||
}
|
||||
|
||||
if declarationList != nil {
|
||||
*declarationList = append(*declarationList, node)
|
||||
}
|
||||
|
||||
if self.token == token.ASSIGN {
|
||||
self.next()
|
||||
node.Initializer = self.parseAssignmentExpression()
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseVariableDeclarationList(var_ file.Idx) []ast.Expression {
|
||||
|
||||
var declarationList []*ast.VariableExpression // Avoid bad expressions
|
||||
var list []ast.Expression
|
||||
|
||||
for {
|
||||
list = append(list, self.parseVariableDeclaration(&declarationList))
|
||||
if self.token != token.COMMA {
|
||||
break
|
||||
}
|
||||
self.next()
|
||||
}
|
||||
|
||||
self.scope.declare(&ast.VariableDeclaration{
|
||||
Var: var_,
|
||||
List: declarationList,
|
||||
})
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
func (self *_parser) parseObjectPropertyKey() (string, string) {
|
||||
idx, tkn, literal := self.idx, self.token, self.literal
|
||||
value := ""
|
||||
self.next()
|
||||
switch tkn {
|
||||
case token.IDENTIFIER:
|
||||
value = literal
|
||||
case token.NUMBER:
|
||||
var err error
|
||||
_, err = parseNumberLiteral(literal)
|
||||
if err != nil {
|
||||
self.error(idx, err.Error())
|
||||
} else {
|
||||
value = literal
|
||||
}
|
||||
case token.STRING:
|
||||
var err error
|
||||
value, err = parseStringLiteral(literal[1 : len(literal)-1])
|
||||
if err != nil {
|
||||
self.error(idx, err.Error())
|
||||
}
|
||||
default:
|
||||
// null, false, class, etc.
|
||||
if matchIdentifier.MatchString(literal) {
|
||||
value = literal
|
||||
}
|
||||
}
|
||||
return literal, value
|
||||
}
|
||||
|
||||
func (self *_parser) parseObjectProperty() ast.Property {
|
||||
|
||||
literal, value := self.parseObjectPropertyKey()
|
||||
if literal == "get" && self.token != token.COLON {
|
||||
idx := self.idx
|
||||
_, value := self.parseObjectPropertyKey()
|
||||
parameterList := self.parseFunctionParameterList()
|
||||
|
||||
node := &ast.FunctionLiteral{
|
||||
Function: idx,
|
||||
ParameterList: parameterList,
|
||||
}
|
||||
self.parseFunctionBlock(node)
|
||||
return ast.Property{
|
||||
Key: value,
|
||||
Kind: "get",
|
||||
Value: node,
|
||||
}
|
||||
} else if literal == "set" && self.token != token.COLON {
|
||||
idx := self.idx
|
||||
_, value := self.parseObjectPropertyKey()
|
||||
parameterList := self.parseFunctionParameterList()
|
||||
|
||||
node := &ast.FunctionLiteral{
|
||||
Function: idx,
|
||||
ParameterList: parameterList,
|
||||
}
|
||||
self.parseFunctionBlock(node)
|
||||
return ast.Property{
|
||||
Key: value,
|
||||
Kind: "set",
|
||||
Value: node,
|
||||
}
|
||||
}
|
||||
|
||||
self.expect(token.COLON)
|
||||
|
||||
return ast.Property{
|
||||
Key: value,
|
||||
Kind: "value",
|
||||
Value: self.parseAssignmentExpression(),
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseObjectLiteral() ast.Expression {
|
||||
var value []ast.Property
|
||||
idx0 := self.expect(token.LEFT_BRACE)
|
||||
for self.token != token.RIGHT_BRACE && self.token != token.EOF {
|
||||
property := self.parseObjectProperty()
|
||||
value = append(value, property)
|
||||
if self.token == token.COMMA {
|
||||
self.next()
|
||||
continue
|
||||
}
|
||||
}
|
||||
idx1 := self.expect(token.RIGHT_BRACE)
|
||||
|
||||
return &ast.ObjectLiteral{
|
||||
LeftBrace: idx0,
|
||||
RightBrace: idx1,
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseArrayLiteral() ast.Expression {
|
||||
|
||||
idx0 := self.expect(token.LEFT_BRACKET)
|
||||
var value []ast.Expression
|
||||
for self.token != token.RIGHT_BRACKET && self.token != token.EOF {
|
||||
if self.token == token.COMMA {
|
||||
self.next()
|
||||
value = append(value, nil)
|
||||
continue
|
||||
}
|
||||
value = append(value, self.parseAssignmentExpression())
|
||||
if self.token != token.RIGHT_BRACKET {
|
||||
self.expect(token.COMMA)
|
||||
}
|
||||
}
|
||||
idx1 := self.expect(token.RIGHT_BRACKET)
|
||||
|
||||
return &ast.ArrayLiteral{
|
||||
LeftBracket: idx0,
|
||||
RightBracket: idx1,
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseArgumentList() (argumentList []ast.Expression, idx0, idx1 file.Idx) {
|
||||
idx0 = self.expect(token.LEFT_PARENTHESIS)
|
||||
if self.token != token.RIGHT_PARENTHESIS {
|
||||
for {
|
||||
argumentList = append(argumentList, self.parseAssignmentExpression())
|
||||
if self.token != token.COMMA {
|
||||
break
|
||||
}
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
idx1 = self.expect(token.RIGHT_PARENTHESIS)
|
||||
return
|
||||
}
|
||||
|
||||
func (self *_parser) parseCallExpression(left ast.Expression) ast.Expression {
|
||||
argumentList, idx0, idx1 := self.parseArgumentList()
|
||||
return &ast.CallExpression{
|
||||
Callee: left,
|
||||
LeftParenthesis: idx0,
|
||||
ArgumentList: argumentList,
|
||||
RightParenthesis: idx1,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseDotMember(left ast.Expression) ast.Expression {
|
||||
period := self.expect(token.PERIOD)
|
||||
|
||||
literal := self.literal
|
||||
idx := self.idx
|
||||
|
||||
if !matchIdentifier.MatchString(literal) {
|
||||
self.expect(token.IDENTIFIER)
|
||||
self.nextStatement()
|
||||
return &ast.BadExpression{From: period, To: self.idx}
|
||||
}
|
||||
|
||||
self.next()
|
||||
|
||||
return &ast.DotExpression{
|
||||
Left: left,
|
||||
Identifier: ast.Identifier{
|
||||
Idx: idx,
|
||||
Name: literal,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseBracketMember(left ast.Expression) ast.Expression {
|
||||
idx0 := self.expect(token.LEFT_BRACKET)
|
||||
member := self.parseExpression()
|
||||
idx1 := self.expect(token.RIGHT_BRACKET)
|
||||
return &ast.BracketExpression{
|
||||
LeftBracket: idx0,
|
||||
Left: left,
|
||||
Member: member,
|
||||
RightBracket: idx1,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseNewExpression() ast.Expression {
|
||||
idx := self.expect(token.NEW)
|
||||
callee := self.parseLeftHandSideExpression()
|
||||
node := &ast.NewExpression{
|
||||
New: idx,
|
||||
Callee: callee,
|
||||
}
|
||||
if self.token == token.LEFT_PARENTHESIS {
|
||||
argumentList, idx0, idx1 := self.parseArgumentList()
|
||||
node.ArgumentList = argumentList
|
||||
node.LeftParenthesis = idx0
|
||||
node.RightParenthesis = idx1
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseLeftHandSideExpression() ast.Expression {
|
||||
|
||||
var left ast.Expression
|
||||
if self.token == token.NEW {
|
||||
left = self.parseNewExpression()
|
||||
} else {
|
||||
left = self.parsePrimaryExpression()
|
||||
}
|
||||
|
||||
for {
|
||||
if self.token == token.PERIOD {
|
||||
left = self.parseDotMember(left)
|
||||
} else if self.token == token.LEFT_BRACE {
|
||||
left = self.parseBracketMember(left)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseLeftHandSideExpressionAllowCall() ast.Expression {
|
||||
|
||||
allowIn := self.scope.allowIn
|
||||
self.scope.allowIn = true
|
||||
defer func() {
|
||||
self.scope.allowIn = allowIn
|
||||
}()
|
||||
|
||||
var left ast.Expression
|
||||
if self.token == token.NEW {
|
||||
left = self.parseNewExpression()
|
||||
} else {
|
||||
left = self.parsePrimaryExpression()
|
||||
}
|
||||
|
||||
for {
|
||||
if self.token == token.PERIOD {
|
||||
left = self.parseDotMember(left)
|
||||
} else if self.token == token.LEFT_BRACKET {
|
||||
left = self.parseBracketMember(left)
|
||||
} else if self.token == token.LEFT_PARENTHESIS {
|
||||
left = self.parseCallExpression(left)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parsePostfixExpression() ast.Expression {
|
||||
operand := self.parseLeftHandSideExpressionAllowCall()
|
||||
|
||||
switch self.token {
|
||||
case token.INCREMENT, token.DECREMENT:
|
||||
// Make sure there is no line terminator here
|
||||
if self.implicitSemicolon {
|
||||
break
|
||||
}
|
||||
tkn := self.token
|
||||
idx := self.idx
|
||||
self.next()
|
||||
switch operand.(type) {
|
||||
case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression:
|
||||
default:
|
||||
self.error(idx, "Invalid left-hand side in assignment")
|
||||
self.nextStatement()
|
||||
return &ast.BadExpression{From: idx, To: self.idx}
|
||||
}
|
||||
return &ast.UnaryExpression{
|
||||
Operator: tkn,
|
||||
Idx: idx,
|
||||
Operand: operand,
|
||||
Postfix: true,
|
||||
}
|
||||
}
|
||||
|
||||
return operand
|
||||
}
|
||||
|
||||
func (self *_parser) parseUnaryExpression() ast.Expression {
|
||||
|
||||
switch self.token {
|
||||
case token.PLUS, token.MINUS, token.NOT, token.BITWISE_NOT:
|
||||
fallthrough
|
||||
case token.DELETE, token.VOID, token.TYPEOF:
|
||||
tkn := self.token
|
||||
idx := self.idx
|
||||
self.next()
|
||||
return &ast.UnaryExpression{
|
||||
Operator: tkn,
|
||||
Idx: idx,
|
||||
Operand: self.parseUnaryExpression(),
|
||||
}
|
||||
case token.INCREMENT, token.DECREMENT:
|
||||
tkn := self.token
|
||||
idx := self.idx
|
||||
self.next()
|
||||
operand := self.parseUnaryExpression()
|
||||
switch operand.(type) {
|
||||
case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression:
|
||||
default:
|
||||
self.error(idx, "Invalid left-hand side in assignment")
|
||||
self.nextStatement()
|
||||
return &ast.BadExpression{From: idx, To: self.idx}
|
||||
}
|
||||
return &ast.UnaryExpression{
|
||||
Operator: tkn,
|
||||
Idx: idx,
|
||||
Operand: operand,
|
||||
}
|
||||
}
|
||||
|
||||
return self.parsePostfixExpression()
|
||||
}
|
||||
|
||||
func (self *_parser) parseMultiplicativeExpression() ast.Expression {
|
||||
next := self.parseUnaryExpression
|
||||
left := next()
|
||||
|
||||
for self.token == token.MULTIPLY || self.token == token.SLASH ||
|
||||
self.token == token.REMAINDER {
|
||||
tkn := self.token
|
||||
self.next()
|
||||
left = &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: next(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseAdditiveExpression() ast.Expression {
|
||||
next := self.parseMultiplicativeExpression
|
||||
left := next()
|
||||
|
||||
for self.token == token.PLUS || self.token == token.MINUS {
|
||||
tkn := self.token
|
||||
self.next()
|
||||
left = &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: next(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseShiftExpression() ast.Expression {
|
||||
next := self.parseAdditiveExpression
|
||||
left := next()
|
||||
|
||||
for self.token == token.SHIFT_LEFT || self.token == token.SHIFT_RIGHT ||
|
||||
self.token == token.UNSIGNED_SHIFT_RIGHT {
|
||||
tkn := self.token
|
||||
self.next()
|
||||
left = &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: next(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseRelationalExpression() ast.Expression {
|
||||
next := self.parseShiftExpression
|
||||
left := next()
|
||||
|
||||
allowIn := self.scope.allowIn
|
||||
self.scope.allowIn = true
|
||||
defer func() {
|
||||
self.scope.allowIn = allowIn
|
||||
}()
|
||||
|
||||
switch self.token {
|
||||
case token.LESS, token.LESS_OR_EQUAL, token.GREATER, token.GREATER_OR_EQUAL:
|
||||
tkn := self.token
|
||||
self.next()
|
||||
return &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: self.parseRelationalExpression(),
|
||||
Comparison: true,
|
||||
}
|
||||
case token.INSTANCEOF:
|
||||
tkn := self.token
|
||||
self.next()
|
||||
return &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: self.parseRelationalExpression(),
|
||||
}
|
||||
case token.IN:
|
||||
if !allowIn {
|
||||
return left
|
||||
}
|
||||
tkn := self.token
|
||||
self.next()
|
||||
return &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: self.parseRelationalExpression(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseEqualityExpression() ast.Expression {
|
||||
next := self.parseRelationalExpression
|
||||
left := next()
|
||||
|
||||
for self.token == token.EQUAL || self.token == token.NOT_EQUAL ||
|
||||
self.token == token.STRICT_EQUAL || self.token == token.STRICT_NOT_EQUAL {
|
||||
tkn := self.token
|
||||
self.next()
|
||||
left = &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: next(),
|
||||
Comparison: true,
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseBitwiseAndExpression() ast.Expression {
|
||||
next := self.parseEqualityExpression
|
||||
left := next()
|
||||
|
||||
for self.token == token.AND {
|
||||
tkn := self.token
|
||||
self.next()
|
||||
left = &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: next(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseBitwiseExclusiveOrExpression() ast.Expression {
|
||||
next := self.parseBitwiseAndExpression
|
||||
left := next()
|
||||
|
||||
for self.token == token.EXCLUSIVE_OR {
|
||||
tkn := self.token
|
||||
self.next()
|
||||
left = &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: next(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseBitwiseOrExpression() ast.Expression {
|
||||
next := self.parseBitwiseExclusiveOrExpression
|
||||
left := next()
|
||||
|
||||
for self.token == token.OR {
|
||||
tkn := self.token
|
||||
self.next()
|
||||
left = &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: next(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseLogicalAndExpression() ast.Expression {
|
||||
next := self.parseBitwiseOrExpression
|
||||
left := next()
|
||||
|
||||
for self.token == token.LOGICAL_AND {
|
||||
tkn := self.token
|
||||
self.next()
|
||||
left = &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: next(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseLogicalOrExpression() ast.Expression {
|
||||
next := self.parseLogicalAndExpression
|
||||
left := next()
|
||||
|
||||
for self.token == token.LOGICAL_OR {
|
||||
tkn := self.token
|
||||
self.next()
|
||||
left = &ast.BinaryExpression{
|
||||
Operator: tkn,
|
||||
Left: left,
|
||||
Right: next(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseConditionlExpression() ast.Expression {
|
||||
left := self.parseLogicalOrExpression()
|
||||
|
||||
if self.token == token.QUESTION_MARK {
|
||||
self.next()
|
||||
consequent := self.parseAssignmentExpression()
|
||||
self.expect(token.COLON)
|
||||
return &ast.ConditionalExpression{
|
||||
Test: left,
|
||||
Consequent: consequent,
|
||||
Alternate: self.parseAssignmentExpression(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseAssignmentExpression() ast.Expression {
|
||||
left := self.parseConditionlExpression()
|
||||
var operator token.Token
|
||||
switch self.token {
|
||||
case token.ASSIGN:
|
||||
operator = self.token
|
||||
case token.ADD_ASSIGN:
|
||||
operator = token.PLUS
|
||||
case token.SUBTRACT_ASSIGN:
|
||||
operator = token.MINUS
|
||||
case token.MULTIPLY_ASSIGN:
|
||||
operator = token.MULTIPLY
|
||||
case token.QUOTIENT_ASSIGN:
|
||||
operator = token.SLASH
|
||||
case token.REMAINDER_ASSIGN:
|
||||
operator = token.REMAINDER
|
||||
case token.AND_ASSIGN:
|
||||
operator = token.AND
|
||||
case token.AND_NOT_ASSIGN:
|
||||
operator = token.AND_NOT
|
||||
case token.OR_ASSIGN:
|
||||
operator = token.OR
|
||||
case token.EXCLUSIVE_OR_ASSIGN:
|
||||
operator = token.EXCLUSIVE_OR
|
||||
case token.SHIFT_LEFT_ASSIGN:
|
||||
operator = token.SHIFT_LEFT
|
||||
case token.SHIFT_RIGHT_ASSIGN:
|
||||
operator = token.SHIFT_RIGHT
|
||||
case token.UNSIGNED_SHIFT_RIGHT_ASSIGN:
|
||||
operator = token.UNSIGNED_SHIFT_RIGHT
|
||||
}
|
||||
|
||||
if operator != 0 {
|
||||
idx := self.idx
|
||||
self.next()
|
||||
switch left.(type) {
|
||||
case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression:
|
||||
default:
|
||||
self.error(left.Idx0(), "Invalid left-hand side in assignment")
|
||||
self.nextStatement()
|
||||
return &ast.BadExpression{From: idx, To: self.idx}
|
||||
}
|
||||
return &ast.AssignExpression{
|
||||
Left: left,
|
||||
Operator: operator,
|
||||
Right: self.parseAssignmentExpression(),
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
|
||||
func (self *_parser) parseExpression() ast.Expression {
|
||||
next := self.parseAssignmentExpression
|
||||
left := next()
|
||||
|
||||
if self.token == token.COMMA {
|
||||
sequence := []ast.Expression{left}
|
||||
for {
|
||||
if self.token != token.COMMA {
|
||||
break
|
||||
}
|
||||
self.next()
|
||||
sequence = append(sequence, next())
|
||||
}
|
||||
return &ast.SequenceExpression{
|
||||
Sequence: sequence,
|
||||
}
|
||||
}
|
||||
|
||||
return left
|
||||
}
|
||||
819
Godeps/_workspace/src/github.com/obscuren/otto/parser/lexer.go
generated
vendored
819
Godeps/_workspace/src/github.com/obscuren/otto/parser/lexer.go
generated
vendored
|
|
@ -1,819 +0,0 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/robertkrimen/otto/file"
|
||||
"github.com/robertkrimen/otto/token"
|
||||
)
|
||||
|
||||
type _chr struct {
|
||||
value rune
|
||||
width int
|
||||
}
|
||||
|
||||
var matchIdentifier = regexp.MustCompile(`^[$_\p{L}][$_\p{L}\d}]*$`)
|
||||
|
||||
func isDecimalDigit(chr rune) bool {
|
||||
return '0' <= chr && chr <= '9'
|
||||
}
|
||||
|
||||
func digitValue(chr rune) int {
|
||||
switch {
|
||||
case '0' <= chr && chr <= '9':
|
||||
return int(chr - '0')
|
||||
case 'a' <= chr && chr <= 'f':
|
||||
return int(chr - 'a' + 10)
|
||||
case 'A' <= chr && chr <= 'F':
|
||||
return int(chr - 'A' + 10)
|
||||
}
|
||||
return 16 // Larger than any legal digit value
|
||||
}
|
||||
|
||||
func isDigit(chr rune, base int) bool {
|
||||
return digitValue(chr) < base
|
||||
}
|
||||
|
||||
func isIdentifierStart(chr rune) bool {
|
||||
return chr == '$' || chr == '_' || chr == '\\' ||
|
||||
'a' <= chr && chr <= 'z' || 'A' <= chr && chr <= 'Z' ||
|
||||
chr >= utf8.RuneSelf && unicode.IsLetter(chr)
|
||||
}
|
||||
|
||||
func isIdentifierPart(chr rune) bool {
|
||||
return chr == '$' || chr == '_' || chr == '\\' ||
|
||||
'a' <= chr && chr <= 'z' || 'A' <= chr && chr <= 'Z' ||
|
||||
'0' <= chr && chr <= '9' ||
|
||||
chr >= utf8.RuneSelf && (unicode.IsLetter(chr) || unicode.IsDigit(chr))
|
||||
}
|
||||
|
||||
func (self *_parser) scanIdentifier() (string, error) {
|
||||
offset := self.chrOffset
|
||||
parse := false
|
||||
for isIdentifierPart(self.chr) {
|
||||
if self.chr == '\\' {
|
||||
distance := self.chrOffset - offset
|
||||
self.read()
|
||||
if self.chr != 'u' {
|
||||
return "", fmt.Errorf("Invalid identifier escape character: %c (%s)", self.chr, string(self.chr))
|
||||
}
|
||||
parse = true
|
||||
var value rune
|
||||
for j := 0; j < 4; j++ {
|
||||
self.read()
|
||||
decimal, ok := hex2decimal(byte(self.chr))
|
||||
if !ok {
|
||||
return "", fmt.Errorf("Invalid identifier escape character: %c (%s)", self.chr, string(self.chr))
|
||||
}
|
||||
value = value<<4 | decimal
|
||||
}
|
||||
if value == '\\' {
|
||||
return "", fmt.Errorf("Invalid identifier escape value: %c (%s)", value, string(value))
|
||||
} else if distance == 0 {
|
||||
if !isIdentifierStart(value) {
|
||||
return "", fmt.Errorf("Invalid identifier escape value: %c (%s)", value, string(value))
|
||||
}
|
||||
} else if distance > 0 {
|
||||
if !isIdentifierPart(value) {
|
||||
return "", fmt.Errorf("Invalid identifier escape value: %c (%s)", value, string(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
self.read()
|
||||
}
|
||||
literal := string(self.str[offset:self.chrOffset])
|
||||
if parse {
|
||||
return parseStringLiteral(literal)
|
||||
}
|
||||
return literal, nil
|
||||
}
|
||||
|
||||
// 7.2
|
||||
func isLineWhiteSpace(chr rune) bool {
|
||||
switch chr {
|
||||
case '\u0009', '\u000b', '\u000c', '\u0020', '\u00a0', '\ufeff':
|
||||
return true
|
||||
case '\u000a', '\u000d', '\u2028', '\u2029':
|
||||
return false
|
||||
case '\u0085':
|
||||
return false
|
||||
}
|
||||
return unicode.IsSpace(chr)
|
||||
}
|
||||
|
||||
// 7.3
|
||||
func isLineTerminator(chr rune) bool {
|
||||
switch chr {
|
||||
case '\u000a', '\u000d', '\u2028', '\u2029':
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *_parser) scan() (tkn token.Token, literal string, idx file.Idx) {
|
||||
|
||||
self.implicitSemicolon = false
|
||||
|
||||
for {
|
||||
self.skipWhiteSpace()
|
||||
|
||||
idx = self.idxOf(self.chrOffset)
|
||||
insertSemicolon := false
|
||||
|
||||
switch chr := self.chr; {
|
||||
case isIdentifierStart(chr):
|
||||
var err error
|
||||
literal, err = self.scanIdentifier()
|
||||
if err != nil {
|
||||
tkn = token.ILLEGAL
|
||||
break
|
||||
}
|
||||
if len(literal) > 1 {
|
||||
// Keywords are longer than 1 character, avoid lookup otherwise
|
||||
var strict bool
|
||||
tkn, strict = token.IsKeyword(literal)
|
||||
|
||||
switch tkn {
|
||||
|
||||
case 0: // Not a keyword
|
||||
if literal == "true" || literal == "false" {
|
||||
self.insertSemicolon = true
|
||||
tkn = token.BOOLEAN
|
||||
return
|
||||
} else if literal == "null" {
|
||||
self.insertSemicolon = true
|
||||
tkn = token.NULL
|
||||
return
|
||||
}
|
||||
|
||||
case token.KEYWORD:
|
||||
tkn = token.KEYWORD
|
||||
if strict {
|
||||
// TODO If strict and in strict mode, then this is not a break
|
||||
break
|
||||
}
|
||||
return
|
||||
|
||||
case
|
||||
token.THIS,
|
||||
token.BREAK,
|
||||
token.THROW, // A newline after a throw is not allowed, but we need to detect it
|
||||
token.RETURN,
|
||||
token.CONTINUE,
|
||||
token.DEBUGGER:
|
||||
self.insertSemicolon = true
|
||||
return
|
||||
|
||||
default:
|
||||
return
|
||||
|
||||
}
|
||||
}
|
||||
self.insertSemicolon = true
|
||||
tkn = token.IDENTIFIER
|
||||
return
|
||||
case '0' <= chr && chr <= '9':
|
||||
self.insertSemicolon = true
|
||||
tkn, literal = self.scanNumericLiteral(false)
|
||||
return
|
||||
default:
|
||||
self.read()
|
||||
switch chr {
|
||||
case -1:
|
||||
if self.insertSemicolon {
|
||||
self.insertSemicolon = false
|
||||
self.implicitSemicolon = true
|
||||
}
|
||||
tkn = token.EOF
|
||||
case '\r', '\n', '\u2028', '\u2029':
|
||||
self.insertSemicolon = false
|
||||
self.implicitSemicolon = true
|
||||
continue
|
||||
case ':':
|
||||
tkn = token.COLON
|
||||
case '.':
|
||||
if digitValue(self.chr) < 10 {
|
||||
insertSemicolon = true
|
||||
tkn, literal = self.scanNumericLiteral(true)
|
||||
} else {
|
||||
tkn = token.PERIOD
|
||||
}
|
||||
case ',':
|
||||
tkn = token.COMMA
|
||||
case ';':
|
||||
tkn = token.SEMICOLON
|
||||
case '(':
|
||||
tkn = token.LEFT_PARENTHESIS
|
||||
case ')':
|
||||
tkn = token.RIGHT_PARENTHESIS
|
||||
insertSemicolon = true
|
||||
case '[':
|
||||
tkn = token.LEFT_BRACKET
|
||||
case ']':
|
||||
tkn = token.RIGHT_BRACKET
|
||||
insertSemicolon = true
|
||||
case '{':
|
||||
tkn = token.LEFT_BRACE
|
||||
case '}':
|
||||
tkn = token.RIGHT_BRACE
|
||||
insertSemicolon = true
|
||||
case '+':
|
||||
tkn = self.switch3(token.PLUS, token.ADD_ASSIGN, '+', token.INCREMENT)
|
||||
if tkn == token.INCREMENT {
|
||||
insertSemicolon = true
|
||||
}
|
||||
case '-':
|
||||
tkn = self.switch3(token.MINUS, token.SUBTRACT_ASSIGN, '-', token.DECREMENT)
|
||||
if tkn == token.DECREMENT {
|
||||
insertSemicolon = true
|
||||
}
|
||||
case '*':
|
||||
tkn = self.switch2(token.MULTIPLY, token.MULTIPLY_ASSIGN)
|
||||
case '/':
|
||||
if self.chr == '/' {
|
||||
self.skipSingleLineComment()
|
||||
continue
|
||||
} else if self.chr == '*' {
|
||||
self.skipMultiLineComment()
|
||||
continue
|
||||
} else {
|
||||
// Could be division, could be RegExp literal
|
||||
tkn = self.switch2(token.SLASH, token.QUOTIENT_ASSIGN)
|
||||
insertSemicolon = true
|
||||
}
|
||||
case '%':
|
||||
tkn = self.switch2(token.REMAINDER, token.REMAINDER_ASSIGN)
|
||||
case '^':
|
||||
tkn = self.switch2(token.EXCLUSIVE_OR, token.EXCLUSIVE_OR_ASSIGN)
|
||||
case '<':
|
||||
tkn = self.switch4(token.LESS, token.LESS_OR_EQUAL, '<', token.SHIFT_LEFT, token.SHIFT_LEFT_ASSIGN)
|
||||
case '>':
|
||||
tkn = self.switch6(token.GREATER, token.GREATER_OR_EQUAL, '>', token.SHIFT_RIGHT, token.SHIFT_RIGHT_ASSIGN, '>', token.UNSIGNED_SHIFT_RIGHT, token.UNSIGNED_SHIFT_RIGHT_ASSIGN)
|
||||
case '=':
|
||||
tkn = self.switch2(token.ASSIGN, token.EQUAL)
|
||||
if tkn == token.EQUAL && self.chr == '=' {
|
||||
self.read()
|
||||
tkn = token.STRICT_EQUAL
|
||||
}
|
||||
case '!':
|
||||
tkn = self.switch2(token.NOT, token.NOT_EQUAL)
|
||||
if tkn == token.NOT_EQUAL && self.chr == '=' {
|
||||
self.read()
|
||||
tkn = token.STRICT_NOT_EQUAL
|
||||
}
|
||||
case '&':
|
||||
if self.chr == '^' {
|
||||
self.read()
|
||||
tkn = self.switch2(token.AND_NOT, token.AND_NOT_ASSIGN)
|
||||
} else {
|
||||
tkn = self.switch3(token.AND, token.AND_ASSIGN, '&', token.LOGICAL_AND)
|
||||
}
|
||||
case '|':
|
||||
tkn = self.switch3(token.OR, token.OR_ASSIGN, '|', token.LOGICAL_OR)
|
||||
case '~':
|
||||
tkn = token.BITWISE_NOT
|
||||
case '?':
|
||||
tkn = token.QUESTION_MARK
|
||||
case '"', '\'':
|
||||
insertSemicolon = true
|
||||
tkn = token.STRING
|
||||
var err error
|
||||
literal, err = self.scanString(self.chrOffset - 1)
|
||||
if err != nil {
|
||||
tkn = token.ILLEGAL
|
||||
}
|
||||
default:
|
||||
self.errorUnexpected(idx, chr)
|
||||
tkn = token.ILLEGAL
|
||||
}
|
||||
}
|
||||
self.insertSemicolon = insertSemicolon
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) switch2(tkn0, tkn1 token.Token) token.Token {
|
||||
if self.chr == '=' {
|
||||
self.read()
|
||||
return tkn1
|
||||
}
|
||||
return tkn0
|
||||
}
|
||||
|
||||
func (self *_parser) switch3(tkn0, tkn1 token.Token, chr2 rune, tkn2 token.Token) token.Token {
|
||||
if self.chr == '=' {
|
||||
self.read()
|
||||
return tkn1
|
||||
}
|
||||
if self.chr == chr2 {
|
||||
self.read()
|
||||
return tkn2
|
||||
}
|
||||
return tkn0
|
||||
}
|
||||
|
||||
func (self *_parser) switch4(tkn0, tkn1 token.Token, chr2 rune, tkn2, tkn3 token.Token) token.Token {
|
||||
if self.chr == '=' {
|
||||
self.read()
|
||||
return tkn1
|
||||
}
|
||||
if self.chr == chr2 {
|
||||
self.read()
|
||||
if self.chr == '=' {
|
||||
self.read()
|
||||
return tkn3
|
||||
}
|
||||
return tkn2
|
||||
}
|
||||
return tkn0
|
||||
}
|
||||
|
||||
func (self *_parser) switch6(tkn0, tkn1 token.Token, chr2 rune, tkn2, tkn3 token.Token, chr3 rune, tkn4, tkn5 token.Token) token.Token {
|
||||
if self.chr == '=' {
|
||||
self.read()
|
||||
return tkn1
|
||||
}
|
||||
if self.chr == chr2 {
|
||||
self.read()
|
||||
if self.chr == '=' {
|
||||
self.read()
|
||||
return tkn3
|
||||
}
|
||||
if self.chr == chr3 {
|
||||
self.read()
|
||||
if self.chr == '=' {
|
||||
self.read()
|
||||
return tkn5
|
||||
}
|
||||
return tkn4
|
||||
}
|
||||
return tkn2
|
||||
}
|
||||
return tkn0
|
||||
}
|
||||
|
||||
func (self *_parser) chrAt(index int) _chr {
|
||||
value, width := utf8.DecodeRuneInString(self.str[index:])
|
||||
return _chr{
|
||||
value: value,
|
||||
width: width,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) _peek() rune {
|
||||
if self.offset+1 < self.length {
|
||||
return rune(self.str[self.offset+1])
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (self *_parser) read() {
|
||||
if self.offset < self.length {
|
||||
self.chrOffset = self.offset
|
||||
chr, width := rune(self.str[self.offset]), 1
|
||||
if chr >= utf8.RuneSelf { // !ASCII
|
||||
chr, width = utf8.DecodeRuneInString(self.str[self.offset:])
|
||||
if chr == utf8.RuneError && width == 1 {
|
||||
self.error(self.chrOffset, "Invalid UTF-8 character")
|
||||
}
|
||||
}
|
||||
self.offset += width
|
||||
self.chr = chr
|
||||
} else {
|
||||
self.chrOffset = self.length
|
||||
self.chr = -1 // EOF
|
||||
}
|
||||
}
|
||||
|
||||
// This is here since the functions are so similar
|
||||
func (self *_RegExp_parser) read() {
|
||||
if self.offset < self.length {
|
||||
self.chrOffset = self.offset
|
||||
chr, width := rune(self.str[self.offset]), 1
|
||||
if chr >= utf8.RuneSelf { // !ASCII
|
||||
chr, width = utf8.DecodeRuneInString(self.str[self.offset:])
|
||||
if chr == utf8.RuneError && width == 1 {
|
||||
self.error(self.chrOffset, "Invalid UTF-8 character")
|
||||
}
|
||||
}
|
||||
self.offset += width
|
||||
self.chr = chr
|
||||
} else {
|
||||
self.chrOffset = self.length
|
||||
self.chr = -1 // EOF
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) skipSingleLineComment() {
|
||||
for self.chr != -1 {
|
||||
self.read()
|
||||
if isLineTerminator(self.chr) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) skipMultiLineComment() {
|
||||
self.read()
|
||||
for self.chr >= 0 {
|
||||
chr := self.chr
|
||||
self.read()
|
||||
if chr == '*' && self.chr == '/' {
|
||||
self.read()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
self.errorUnexpected(0, self.chr)
|
||||
}
|
||||
|
||||
func (self *_parser) skipWhiteSpace() {
|
||||
for {
|
||||
switch self.chr {
|
||||
case ' ', '\t', '\f', '\v', '\u00a0', '\ufeff':
|
||||
self.read()
|
||||
continue
|
||||
case '\r':
|
||||
if self._peek() == '\n' {
|
||||
self.read()
|
||||
}
|
||||
fallthrough
|
||||
case '\u2028', '\u2029', '\n':
|
||||
if self.insertSemicolon {
|
||||
return
|
||||
}
|
||||
self.read()
|
||||
continue
|
||||
}
|
||||
if self.chr >= utf8.RuneSelf {
|
||||
if unicode.IsSpace(self.chr) {
|
||||
self.read()
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) skipLineWhiteSpace() {
|
||||
for isLineWhiteSpace(self.chr) {
|
||||
self.read()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) scanMantissa(base int) {
|
||||
for digitValue(self.chr) < base {
|
||||
self.read()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) scanEscape(quote rune) {
|
||||
|
||||
var length, base uint32
|
||||
switch self.chr {
|
||||
//case '0', '1', '2', '3', '4', '5', '6', '7':
|
||||
// Octal:
|
||||
// length, base, limit = 3, 8, 255
|
||||
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"', '\'', '0':
|
||||
self.read()
|
||||
return
|
||||
case '\r', '\n', '\u2028', '\u2029':
|
||||
self.scanNewline()
|
||||
return
|
||||
case 'x':
|
||||
self.read()
|
||||
length, base = 2, 16
|
||||
case 'u':
|
||||
self.read()
|
||||
length, base = 4, 16
|
||||
default:
|
||||
self.read() // Always make progress
|
||||
return
|
||||
}
|
||||
|
||||
var value uint32
|
||||
for ; length > 0 && self.chr != quote && self.chr >= 0; length-- {
|
||||
digit := uint32(digitValue(self.chr))
|
||||
if digit >= base {
|
||||
break
|
||||
}
|
||||
value = value*base + digit
|
||||
self.read()
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) scanString(offset int) (string, error) {
|
||||
// " ' /
|
||||
quote := rune(self.str[offset])
|
||||
|
||||
for self.chr != quote {
|
||||
chr := self.chr
|
||||
if chr == '\n' || chr == '\r' || chr == '\u2028' || chr == '\u2029' || chr < 0 {
|
||||
goto newline
|
||||
}
|
||||
self.read()
|
||||
if chr == '\\' {
|
||||
if quote == '/' {
|
||||
if self.chr == '\n' || self.chr == '\r' || self.chr == '\u2028' || self.chr == '\u2029' || self.chr < 0 {
|
||||
goto newline
|
||||
}
|
||||
self.read()
|
||||
} else {
|
||||
self.scanEscape(quote)
|
||||
}
|
||||
} else if chr == '[' && quote == '/' {
|
||||
// Allow a slash (/) in a bracket character class ([...])
|
||||
// TODO Fix this, this is hacky...
|
||||
quote = -1
|
||||
} else if chr == ']' && quote == -1 {
|
||||
quote = '/'
|
||||
}
|
||||
}
|
||||
|
||||
// " ' /
|
||||
self.read()
|
||||
|
||||
return string(self.str[offset:self.chrOffset]), nil
|
||||
|
||||
newline:
|
||||
self.scanNewline()
|
||||
err := "String not terminated"
|
||||
if quote == '/' {
|
||||
err = "Invalid regular expression: missing /"
|
||||
self.error(self.idxOf(offset), err)
|
||||
}
|
||||
return "", errors.New(err)
|
||||
}
|
||||
|
||||
func (self *_parser) scanNewline() {
|
||||
if self.chr == '\r' {
|
||||
self.read()
|
||||
if self.chr != '\n' {
|
||||
return
|
||||
}
|
||||
}
|
||||
self.read()
|
||||
}
|
||||
|
||||
func hex2decimal(chr byte) (value rune, ok bool) {
|
||||
{
|
||||
chr := rune(chr)
|
||||
switch {
|
||||
case '0' <= chr && chr <= '9':
|
||||
return chr - '0', true
|
||||
case 'a' <= chr && chr <= 'f':
|
||||
return chr - 'a' + 10, true
|
||||
case 'A' <= chr && chr <= 'F':
|
||||
return chr - 'A' + 10, true
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
parseIntErr := err // Save this first error, just in case
|
||||
|
||||
value, err = strconv.ParseFloat(literal, 64)
|
||||
if err == nil {
|
||||
return
|
||||
} else if err.(*strconv.NumError).Err == strconv.ErrRange {
|
||||
// Infinity, etc.
|
||||
return value, nil
|
||||
}
|
||||
|
||||
err = parseIntErr
|
||||
|
||||
if err.(*strconv.NumError).Err == strconv.ErrRange {
|
||||
if len(literal) > 2 && literal[0] == '0' && (literal[1] == 'X' || literal[1] == 'x') {
|
||||
// Could just be a very large number (e.g. 0x8000000000000000)
|
||||
var value float64
|
||||
literal = literal[2:]
|
||||
for _, chr := range literal {
|
||||
digit := digitValue(chr)
|
||||
if digit >= 16 {
|
||||
goto error
|
||||
}
|
||||
value = value*16 + float64(digit)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
return nil, errors.New("Illegal numeric literal")
|
||||
}
|
||||
|
||||
func parseStringLiteral(literal string) (string, error) {
|
||||
// Best case scenario...
|
||||
if literal == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Slightly less-best case scenario...
|
||||
if !strings.ContainsRune(literal, '\\') {
|
||||
return literal, nil
|
||||
}
|
||||
|
||||
str := literal
|
||||
buffer := bytes.NewBuffer(make([]byte, 0, 3*len(literal)/2))
|
||||
|
||||
for len(str) > 0 {
|
||||
switch chr := str[0]; {
|
||||
// We do not explicitly handle the case of the quote
|
||||
// value, which can be: " ' /
|
||||
// This assumes we're already passed a partially well-formed literal
|
||||
case chr >= utf8.RuneSelf:
|
||||
chr, size := utf8.DecodeRuneInString(str)
|
||||
buffer.WriteRune(chr)
|
||||
str = str[size:]
|
||||
continue
|
||||
case chr != '\\':
|
||||
buffer.WriteByte(chr)
|
||||
str = str[1:]
|
||||
continue
|
||||
}
|
||||
|
||||
if len(str) <= 1 {
|
||||
panic("len(str) <= 1")
|
||||
}
|
||||
chr := str[1]
|
||||
var value rune
|
||||
if chr >= utf8.RuneSelf {
|
||||
str = str[1:]
|
||||
var size int
|
||||
value, size = utf8.DecodeRuneInString(str)
|
||||
str = str[size:] // \ + <character>
|
||||
} else {
|
||||
str = str[2:] // \<character>
|
||||
switch chr {
|
||||
case 'b':
|
||||
value = '\b'
|
||||
case 'f':
|
||||
value = '\f'
|
||||
case 'n':
|
||||
value = '\n'
|
||||
case 'r':
|
||||
value = '\r'
|
||||
case 't':
|
||||
value = '\t'
|
||||
case 'v':
|
||||
value = '\v'
|
||||
case 'x', 'u':
|
||||
size := 0
|
||||
switch chr {
|
||||
case 'x':
|
||||
size = 2
|
||||
case 'u':
|
||||
size = 4
|
||||
}
|
||||
if len(str) < size {
|
||||
return "", fmt.Errorf("invalid escape: \\%s: len(%q) != %d", string(chr), str, size)
|
||||
}
|
||||
for j := 0; j < size; j++ {
|
||||
decimal, ok := hex2decimal(str[j])
|
||||
if !ok {
|
||||
return "", fmt.Errorf("invalid escape: \\%s: %q", string(chr), str[:size])
|
||||
}
|
||||
value = value<<4 | decimal
|
||||
}
|
||||
str = str[size:]
|
||||
if chr == 'x' {
|
||||
break
|
||||
}
|
||||
if value > utf8.MaxRune {
|
||||
panic("value > utf8.MaxRune")
|
||||
}
|
||||
case '0':
|
||||
if len(str) == 0 || '0' > str[0] || str[0] > '7' {
|
||||
value = 0
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
case '1', '2', '3', '4', '5', '6', '7':
|
||||
// TODO strict
|
||||
value = rune(chr) - '0'
|
||||
j := 0
|
||||
for ; j < 2; j++ {
|
||||
if len(str) < j+1 {
|
||||
break
|
||||
}
|
||||
chr := str[j]
|
||||
if '0' > chr || chr > '7' {
|
||||
break
|
||||
}
|
||||
decimal := rune(str[j]) - '0'
|
||||
value = (value << 3) | decimal
|
||||
}
|
||||
str = str[j:]
|
||||
case '\\':
|
||||
value = '\\'
|
||||
case '\'', '"':
|
||||
value = rune(chr)
|
||||
case '\r':
|
||||
if len(str) > 0 {
|
||||
if str[0] == '\n' {
|
||||
str = str[1:]
|
||||
}
|
||||
}
|
||||
fallthrough
|
||||
case '\n':
|
||||
continue
|
||||
default:
|
||||
value = rune(chr)
|
||||
}
|
||||
}
|
||||
buffer.WriteRune(value)
|
||||
}
|
||||
|
||||
return buffer.String(), nil
|
||||
}
|
||||
|
||||
func (self *_parser) scanNumericLiteral(decimalPoint bool) (token.Token, string) {
|
||||
|
||||
offset := self.chrOffset
|
||||
tkn := token.NUMBER
|
||||
|
||||
if decimalPoint {
|
||||
offset--
|
||||
self.scanMantissa(10)
|
||||
goto exponent
|
||||
}
|
||||
|
||||
if self.chr == '0' {
|
||||
offset := self.chrOffset
|
||||
self.read()
|
||||
if self.chr == 'x' || self.chr == 'X' {
|
||||
// Hexadecimal
|
||||
self.read()
|
||||
if isDigit(self.chr, 16) {
|
||||
self.read()
|
||||
} else {
|
||||
return token.ILLEGAL, self.str[offset:self.chrOffset]
|
||||
}
|
||||
self.scanMantissa(16)
|
||||
|
||||
if self.chrOffset-offset <= 2 {
|
||||
// Only "0x" or "0X"
|
||||
self.error(0, "Illegal hexadecimal number")
|
||||
}
|
||||
|
||||
goto hexadecimal
|
||||
} else if self.chr == '.' {
|
||||
// Float
|
||||
goto float
|
||||
} else {
|
||||
// Octal, Float
|
||||
if self.chr == 'e' || self.chr == 'E' {
|
||||
goto exponent
|
||||
}
|
||||
self.scanMantissa(8)
|
||||
if self.chr == '8' || self.chr == '9' {
|
||||
return token.ILLEGAL, self.str[offset:self.chrOffset]
|
||||
}
|
||||
goto octal
|
||||
}
|
||||
}
|
||||
|
||||
self.scanMantissa(10)
|
||||
|
||||
float:
|
||||
if self.chr == '.' {
|
||||
self.read()
|
||||
self.scanMantissa(10)
|
||||
}
|
||||
|
||||
exponent:
|
||||
if self.chr == 'e' || self.chr == 'E' {
|
||||
self.read()
|
||||
if self.chr == '-' || self.chr == '+' {
|
||||
self.read()
|
||||
}
|
||||
if isDecimalDigit(self.chr) {
|
||||
self.read()
|
||||
self.scanMantissa(10)
|
||||
} else {
|
||||
return token.ILLEGAL, self.str[offset:self.chrOffset]
|
||||
}
|
||||
}
|
||||
|
||||
hexadecimal:
|
||||
octal:
|
||||
if isIdentifierStart(self.chr) || isDecimalDigit(self.chr) {
|
||||
return token.ILLEGAL, self.str[offset:self.chrOffset]
|
||||
}
|
||||
|
||||
return tkn, self.str[offset:self.chrOffset]
|
||||
}
|
||||
380
Godeps/_workspace/src/github.com/obscuren/otto/parser/lexer_test.go
generated
vendored
380
Godeps/_workspace/src/github.com/obscuren/otto/parser/lexer_test.go
generated
vendored
|
|
@ -1,380 +0,0 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"../terst"
|
||||
"testing"
|
||||
|
||||
"github.com/robertkrimen/otto/file"
|
||||
"github.com/robertkrimen/otto/token"
|
||||
)
|
||||
|
||||
var tt = terst.Terst
|
||||
var is = terst.Is
|
||||
|
||||
func TestLexer(t *testing.T) {
|
||||
tt(t, func() {
|
||||
setup := func(src string) *_parser {
|
||||
parser := newParser("", src)
|
||||
return parser
|
||||
}
|
||||
|
||||
test := func(src string, test ...interface{}) {
|
||||
parser := setup(src)
|
||||
for len(test) > 0 {
|
||||
tkn, literal, idx := parser.scan()
|
||||
if len(test) > 0 {
|
||||
is(tkn, test[0].(token.Token))
|
||||
test = test[1:]
|
||||
}
|
||||
if len(test) > 0 {
|
||||
is(literal, test[0].(string))
|
||||
test = test[1:]
|
||||
}
|
||||
if len(test) > 0 {
|
||||
// FIXME terst, Fix this so that cast to file.Idx is not necessary?
|
||||
is(idx, file.Idx(test[0].(int)))
|
||||
test = test[1:]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test("",
|
||||
token.EOF, "", 1,
|
||||
)
|
||||
|
||||
test("1",
|
||||
token.NUMBER, "1", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
|
||||
test(".0",
|
||||
token.NUMBER, ".0", 1,
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
|
||||
test("abc",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
|
||||
test("abc(1)",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.LEFT_PARENTHESIS, "", 4,
|
||||
token.NUMBER, "1", 5,
|
||||
token.RIGHT_PARENTHESIS, "", 6,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
|
||||
test(".",
|
||||
token.PERIOD, "", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
|
||||
test("===.",
|
||||
token.STRICT_EQUAL, "", 1,
|
||||
token.PERIOD, "", 4,
|
||||
token.EOF, "", 5,
|
||||
)
|
||||
|
||||
test(">>>=.0",
|
||||
token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
token.NUMBER, ".0", 5,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
|
||||
test(">>>=0.0.",
|
||||
token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
token.NUMBER, "0.0", 5,
|
||||
token.PERIOD, "", 8,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
|
||||
test("\"abc\"",
|
||||
token.STRING, "\"abc\"", 1,
|
||||
token.EOF, "", 6,
|
||||
)
|
||||
|
||||
test("abc = //",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
|
||||
test("abc = 1 / 2",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NUMBER, "1", 7,
|
||||
token.SLASH, "", 9,
|
||||
token.NUMBER, "2", 11,
|
||||
token.EOF, "", 12,
|
||||
)
|
||||
|
||||
test("xyzzy = 'Nothing happens.'",
|
||||
token.IDENTIFIER, "xyzzy", 1,
|
||||
token.ASSIGN, "", 7,
|
||||
token.STRING, "'Nothing happens.'", 9,
|
||||
token.EOF, "", 27,
|
||||
)
|
||||
|
||||
test("abc = !false",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NOT, "", 7,
|
||||
token.BOOLEAN, "false", 8,
|
||||
token.EOF, "", 13,
|
||||
)
|
||||
|
||||
test("abc = !!true",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NOT, "", 7,
|
||||
token.NOT, "", 8,
|
||||
token.BOOLEAN, "true", 9,
|
||||
token.EOF, "", 13,
|
||||
)
|
||||
|
||||
test("abc *= 1",
|
||||
token.IDENTIFIER, "abc", 1,
|
||||
token.MULTIPLY_ASSIGN, "", 5,
|
||||
token.NUMBER, "1", 8,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
|
||||
test("if 1 else",
|
||||
token.IF, "if", 1,
|
||||
token.NUMBER, "1", 4,
|
||||
token.ELSE, "else", 6,
|
||||
token.EOF, "", 10,
|
||||
)
|
||||
|
||||
test("null",
|
||||
token.NULL, "null", 1,
|
||||
token.EOF, "", 5,
|
||||
)
|
||||
|
||||
test(`"\u007a\x79\u000a\x78"`,
|
||||
token.STRING, "\"\\u007a\\x79\\u000a\\x78\"", 1,
|
||||
token.EOF, "", 23,
|
||||
)
|
||||
|
||||
test(`"[First line \
|
||||
Second line \
|
||||
Third line\
|
||||
. ]"
|
||||
`,
|
||||
token.STRING, "\"[First line \\\nSecond line \\\n Third line\\\n. ]\"", 1,
|
||||
token.EOF, "", 53,
|
||||
)
|
||||
|
||||
test("/",
|
||||
token.SLASH, "", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
|
||||
test("var abc = \"abc\uFFFFabc\"",
|
||||
token.VAR, "var", 1,
|
||||
token.IDENTIFIER, "abc", 5,
|
||||
token.ASSIGN, "", 9,
|
||||
token.STRING, "\"abc\uFFFFabc\"", 11,
|
||||
token.EOF, "", 22,
|
||||
)
|
||||
|
||||
test(`'\t' === '\r'`,
|
||||
token.STRING, "'\\t'", 1,
|
||||
token.STRICT_EQUAL, "", 6,
|
||||
token.STRING, "'\\r'", 10,
|
||||
token.EOF, "", 14,
|
||||
)
|
||||
|
||||
test(`var \u0024 = 1`,
|
||||
token.VAR, "var", 1,
|
||||
token.IDENTIFIER, "$", 5,
|
||||
token.ASSIGN, "", 12,
|
||||
token.NUMBER, "1", 14,
|
||||
token.EOF, "", 15,
|
||||
)
|
||||
|
||||
test("10e10000",
|
||||
token.NUMBER, "10e10000", 1,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
|
||||
test(`var if var class`,
|
||||
token.VAR, "var", 1,
|
||||
token.IF, "if", 5,
|
||||
token.VAR, "var", 8,
|
||||
token.KEYWORD, "class", 12,
|
||||
token.EOF, "", 17,
|
||||
)
|
||||
|
||||
test(`-0`,
|
||||
token.MINUS, "", 1,
|
||||
token.NUMBER, "0", 2,
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
|
||||
test(`.01`,
|
||||
token.NUMBER, ".01", 1,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
|
||||
test(`.01e+2`,
|
||||
token.NUMBER, ".01e+2", 1,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
|
||||
test(";",
|
||||
token.SEMICOLON, "", 1,
|
||||
token.EOF, "", 2,
|
||||
)
|
||||
|
||||
test(";;",
|
||||
token.SEMICOLON, "", 1,
|
||||
token.SEMICOLON, "", 2,
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
|
||||
test("//",
|
||||
token.EOF, "", 3,
|
||||
)
|
||||
|
||||
test(";;//",
|
||||
token.SEMICOLON, "", 1,
|
||||
token.SEMICOLON, "", 2,
|
||||
token.EOF, "", 5,
|
||||
)
|
||||
|
||||
test("1",
|
||||
token.NUMBER, "1", 1,
|
||||
)
|
||||
|
||||
test("12 123",
|
||||
token.NUMBER, "12", 1,
|
||||
token.NUMBER, "123", 4,
|
||||
)
|
||||
|
||||
test("1.2 12.3",
|
||||
token.NUMBER, "1.2", 1,
|
||||
token.NUMBER, "12.3", 5,
|
||||
)
|
||||
|
||||
test("/ /=",
|
||||
token.SLASH, "", 1,
|
||||
token.QUOTIENT_ASSIGN, "", 3,
|
||||
)
|
||||
|
||||
test(`"abc"`,
|
||||
token.STRING, `"abc"`, 1,
|
||||
)
|
||||
|
||||
test(`'abc'`,
|
||||
token.STRING, `'abc'`, 1,
|
||||
)
|
||||
|
||||
test("++",
|
||||
token.INCREMENT, "", 1,
|
||||
)
|
||||
|
||||
test(">",
|
||||
token.GREATER, "", 1,
|
||||
)
|
||||
|
||||
test(">=",
|
||||
token.GREATER_OR_EQUAL, "", 1,
|
||||
)
|
||||
|
||||
test(">>",
|
||||
token.SHIFT_RIGHT, "", 1,
|
||||
)
|
||||
|
||||
test(">>=",
|
||||
token.SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
)
|
||||
|
||||
test(">>>",
|
||||
token.UNSIGNED_SHIFT_RIGHT, "", 1,
|
||||
)
|
||||
|
||||
test(">>>=",
|
||||
token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
|
||||
)
|
||||
|
||||
test("1 \"abc\"",
|
||||
token.NUMBER, "1", 1,
|
||||
token.STRING, "\"abc\"", 3,
|
||||
)
|
||||
|
||||
test(",",
|
||||
token.COMMA, "", 1,
|
||||
)
|
||||
|
||||
test("1, \"abc\"",
|
||||
token.NUMBER, "1", 1,
|
||||
token.COMMA, "", 2,
|
||||
token.STRING, "\"abc\"", 4,
|
||||
)
|
||||
|
||||
test("new abc(1, 3.14159);",
|
||||
token.NEW, "new", 1,
|
||||
token.IDENTIFIER, "abc", 5,
|
||||
token.LEFT_PARENTHESIS, "", 8,
|
||||
token.NUMBER, "1", 9,
|
||||
token.COMMA, "", 10,
|
||||
token.NUMBER, "3.14159", 12,
|
||||
token.RIGHT_PARENTHESIS, "", 19,
|
||||
token.SEMICOLON, "", 20,
|
||||
)
|
||||
|
||||
test("1 == \"1\"",
|
||||
token.NUMBER, "1", 1,
|
||||
token.EQUAL, "", 3,
|
||||
token.STRING, "\"1\"", 6,
|
||||
)
|
||||
|
||||
test("1\n[]\n",
|
||||
token.NUMBER, "1", 1,
|
||||
token.LEFT_BRACKET, "", 3,
|
||||
token.RIGHT_BRACKET, "", 4,
|
||||
)
|
||||
|
||||
test("1\ufeff[]\ufeff",
|
||||
token.NUMBER, "1", 1,
|
||||
token.LEFT_BRACKET, "", 5,
|
||||
token.RIGHT_BRACKET, "", 6,
|
||||
)
|
||||
|
||||
// ILLEGAL
|
||||
|
||||
test(`3ea`,
|
||||
token.ILLEGAL, "3e", 1,
|
||||
token.IDENTIFIER, "a", 3,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
|
||||
test(`3in`,
|
||||
token.ILLEGAL, "3", 1,
|
||||
token.IN, "in", 2,
|
||||
token.EOF, "", 4,
|
||||
)
|
||||
|
||||
test("\"Hello\nWorld\"",
|
||||
token.ILLEGAL, "", 1,
|
||||
token.IDENTIFIER, "World", 8,
|
||||
token.ILLEGAL, "", 13,
|
||||
token.EOF, "", 14,
|
||||
)
|
||||
|
||||
test("\u203f = 10",
|
||||
token.ILLEGAL, "", 1,
|
||||
token.ASSIGN, "", 5,
|
||||
token.NUMBER, "10", 7,
|
||||
token.EOF, "", 9,
|
||||
)
|
||||
|
||||
test(`"\x0G"`,
|
||||
token.STRING, "\"\\x0G\"", 1,
|
||||
token.EOF, "", 7,
|
||||
)
|
||||
|
||||
})
|
||||
}
|
||||
930
Godeps/_workspace/src/github.com/obscuren/otto/parser/marshal_test.go
generated
vendored
930
Godeps/_workspace/src/github.com/obscuren/otto/parser/marshal_test.go
generated
vendored
|
|
@ -1,930 +0,0 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
)
|
||||
|
||||
func marshal(name string, children ...interface{}) interface{} {
|
||||
if len(children) == 1 {
|
||||
if name == "" {
|
||||
return testMarshalNode(children[0])
|
||||
}
|
||||
return map[string]interface{}{
|
||||
name: children[0],
|
||||
}
|
||||
}
|
||||
map_ := map[string]interface{}{}
|
||||
length := len(children) / 2
|
||||
for i := 0; i < length; i++ {
|
||||
name := children[i*2].(string)
|
||||
value := children[i*2+1]
|
||||
map_[name] = value
|
||||
}
|
||||
if name == "" {
|
||||
return map_
|
||||
}
|
||||
return map[string]interface{}{
|
||||
name: map_,
|
||||
}
|
||||
}
|
||||
|
||||
func testMarshalNode(node interface{}) interface{} {
|
||||
switch node := node.(type) {
|
||||
|
||||
// Expression
|
||||
|
||||
case *ast.ArrayLiteral:
|
||||
return marshal("Array", testMarshalNode(node.Value))
|
||||
|
||||
case *ast.AssignExpression:
|
||||
return marshal("Assign",
|
||||
"Left", testMarshalNode(node.Left),
|
||||
"Right", testMarshalNode(node.Right),
|
||||
)
|
||||
|
||||
case *ast.BinaryExpression:
|
||||
return marshal("BinaryExpression",
|
||||
"Operator", node.Operator.String(),
|
||||
"Left", testMarshalNode(node.Left),
|
||||
"Right", testMarshalNode(node.Right),
|
||||
)
|
||||
|
||||
case *ast.BooleanLiteral:
|
||||
return marshal("Literal", node.Value)
|
||||
|
||||
case *ast.CallExpression:
|
||||
return marshal("Call",
|
||||
"Callee", testMarshalNode(node.Callee),
|
||||
"ArgumentList", testMarshalNode(node.ArgumentList),
|
||||
)
|
||||
|
||||
case *ast.ConditionalExpression:
|
||||
return marshal("Conditional",
|
||||
"Test", testMarshalNode(node.Test),
|
||||
"Consequent", testMarshalNode(node.Consequent),
|
||||
"Alternate", testMarshalNode(node.Alternate),
|
||||
)
|
||||
|
||||
case *ast.DotExpression:
|
||||
return marshal("Dot",
|
||||
"Left", testMarshalNode(node.Left),
|
||||
"Member", node.Identifier.Name,
|
||||
)
|
||||
|
||||
case *ast.NewExpression:
|
||||
return marshal("New",
|
||||
"Callee", testMarshalNode(node.Callee),
|
||||
"ArgumentList", testMarshalNode(node.ArgumentList),
|
||||
)
|
||||
|
||||
case *ast.NullLiteral:
|
||||
return marshal("Literal", nil)
|
||||
|
||||
case *ast.NumberLiteral:
|
||||
return marshal("Literal", node.Value)
|
||||
|
||||
case *ast.ObjectLiteral:
|
||||
return marshal("Object", testMarshalNode(node.Value))
|
||||
|
||||
case *ast.RegExpLiteral:
|
||||
return marshal("Literal", node.Literal)
|
||||
|
||||
case *ast.StringLiteral:
|
||||
return marshal("Literal", node.Literal)
|
||||
|
||||
case *ast.VariableExpression:
|
||||
return []interface{}{node.Name, testMarshalNode(node.Initializer)}
|
||||
|
||||
// Statement
|
||||
|
||||
case *ast.Program:
|
||||
return testMarshalNode(node.Body)
|
||||
|
||||
case *ast.BlockStatement:
|
||||
return marshal("BlockStatement", testMarshalNode(node.List))
|
||||
|
||||
case *ast.EmptyStatement:
|
||||
return "EmptyStatement"
|
||||
|
||||
case *ast.ExpressionStatement:
|
||||
return testMarshalNode(node.Expression)
|
||||
|
||||
case *ast.ForInStatement:
|
||||
return marshal("ForIn",
|
||||
"Into", marshal("", node.Into),
|
||||
"Source", marshal("", node.Source),
|
||||
"Body", marshal("", node.Body),
|
||||
)
|
||||
|
||||
case *ast.FunctionLiteral:
|
||||
return marshal("Function", testMarshalNode(node.Body))
|
||||
|
||||
case *ast.Identifier:
|
||||
return marshal("Identifier", node.Name)
|
||||
|
||||
case *ast.IfStatement:
|
||||
if_ := marshal("",
|
||||
"Test", testMarshalNode(node.Test),
|
||||
"Consequent", testMarshalNode(node.Consequent),
|
||||
).(map[string]interface{})
|
||||
if node.Alternate != nil {
|
||||
if_["Alternate"] = testMarshalNode(node.Alternate)
|
||||
}
|
||||
return marshal("If", if_)
|
||||
|
||||
case *ast.LabelledStatement:
|
||||
return marshal("Label",
|
||||
"Name", node.Label.Name,
|
||||
"Statement", testMarshalNode(node.Statement),
|
||||
)
|
||||
case ast.Property:
|
||||
return marshal("",
|
||||
"Key", node.Key,
|
||||
"Value", testMarshalNode(node.Value),
|
||||
)
|
||||
|
||||
case *ast.ReturnStatement:
|
||||
return marshal("Return", testMarshalNode(node.Argument))
|
||||
|
||||
case *ast.SequenceExpression:
|
||||
return marshal("Sequence", testMarshalNode(node.Sequence))
|
||||
|
||||
case *ast.ThrowStatement:
|
||||
return marshal("Throw", testMarshalNode(node.Argument))
|
||||
|
||||
case *ast.VariableStatement:
|
||||
return marshal("Var", testMarshalNode(node.List))
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
value := reflect.ValueOf(node)
|
||||
if value.Kind() == reflect.Slice {
|
||||
tmp0 := []interface{}{}
|
||||
for index := 0; index < value.Len(); index++ {
|
||||
tmp0 = append(tmp0, testMarshalNode(value.Index(index).Interface()))
|
||||
}
|
||||
return tmp0
|
||||
}
|
||||
}
|
||||
|
||||
if node != nil {
|
||||
fmt.Fprintf(os.Stderr, "testMarshalNode(%T)\n", node)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testMarshal(node interface{}) string {
|
||||
value, err := json.Marshal(testMarshalNode(node))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(value)
|
||||
}
|
||||
|
||||
func TestParserAST(t *testing.T) {
|
||||
tt(t, func() {
|
||||
|
||||
test := func(inputOutput string) {
|
||||
match := matchBeforeAfterSeparator.FindStringIndex(inputOutput)
|
||||
input := strings.TrimSpace(inputOutput[0:match[0]])
|
||||
wantOutput := strings.TrimSpace(inputOutput[match[1]:])
|
||||
_, program, err := testParse(input)
|
||||
is(err, nil)
|
||||
haveOutput := testMarshal(program)
|
||||
tmp0, tmp1 := bytes.Buffer{}, bytes.Buffer{}
|
||||
json.Indent(&tmp0, []byte(haveOutput), "\t\t", " ")
|
||||
json.Indent(&tmp1, []byte(wantOutput), "\t\t", " ")
|
||||
is("\n\t\t"+tmp0.String(), "\n\t\t"+tmp1.String())
|
||||
}
|
||||
|
||||
test(`
|
||||
---
|
||||
[]
|
||||
`)
|
||||
|
||||
test(`
|
||||
;
|
||||
---
|
||||
[
|
||||
"EmptyStatement"
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
;;;
|
||||
---
|
||||
[
|
||||
"EmptyStatement",
|
||||
"EmptyStatement",
|
||||
"EmptyStatement"
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
1; true; abc; "abc"; null;
|
||||
---
|
||||
[
|
||||
{
|
||||
"Literal": 1
|
||||
},
|
||||
{
|
||||
"Literal": true
|
||||
},
|
||||
{
|
||||
"Identifier": "abc"
|
||||
},
|
||||
{
|
||||
"Literal": "\"abc\""
|
||||
},
|
||||
{
|
||||
"Literal": null
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
{ 1; null; 3.14159; ; }
|
||||
---
|
||||
[
|
||||
{
|
||||
"BlockStatement": [
|
||||
{
|
||||
"Literal": 1
|
||||
},
|
||||
{
|
||||
"Literal": null
|
||||
},
|
||||
{
|
||||
"Literal": 3.14159
|
||||
},
|
||||
"EmptyStatement"
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
new abc();
|
||||
---
|
||||
[
|
||||
{
|
||||
"New": {
|
||||
"ArgumentList": [],
|
||||
"Callee": {
|
||||
"Identifier": "abc"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
new abc(1, 3.14159)
|
||||
---
|
||||
[
|
||||
{
|
||||
"New": {
|
||||
"ArgumentList": [
|
||||
{
|
||||
"Literal": 1
|
||||
},
|
||||
{
|
||||
"Literal": 3.14159
|
||||
}
|
||||
],
|
||||
"Callee": {
|
||||
"Identifier": "abc"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
true ? false : true
|
||||
---
|
||||
[
|
||||
{
|
||||
"Conditional": {
|
||||
"Alternate": {
|
||||
"Literal": true
|
||||
},
|
||||
"Consequent": {
|
||||
"Literal": false
|
||||
},
|
||||
"Test": {
|
||||
"Literal": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
true || false
|
||||
---
|
||||
[
|
||||
{
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"Literal": true
|
||||
},
|
||||
"Operator": "||",
|
||||
"Right": {
|
||||
"Literal": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
0 + { abc: true }
|
||||
---
|
||||
[
|
||||
{
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"Literal": 0
|
||||
},
|
||||
"Operator": "+",
|
||||
"Right": {
|
||||
"Object": [
|
||||
{
|
||||
"Key": "abc",
|
||||
"Value": {
|
||||
"Literal": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
1 == "1"
|
||||
---
|
||||
[
|
||||
{
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"Literal": 1
|
||||
},
|
||||
"Operator": "==",
|
||||
"Right": {
|
||||
"Literal": "\"1\""
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
abc(1)
|
||||
---
|
||||
[
|
||||
{
|
||||
"Call": {
|
||||
"ArgumentList": [
|
||||
{
|
||||
"Literal": 1
|
||||
}
|
||||
],
|
||||
"Callee": {
|
||||
"Identifier": "abc"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
Math.pow(3, 2)
|
||||
---
|
||||
[
|
||||
{
|
||||
"Call": {
|
||||
"ArgumentList": [
|
||||
{
|
||||
"Literal": 3
|
||||
},
|
||||
{
|
||||
"Literal": 2
|
||||
}
|
||||
],
|
||||
"Callee": {
|
||||
"Dot": {
|
||||
"Left": {
|
||||
"Identifier": "Math"
|
||||
},
|
||||
"Member": "pow"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
1, 2, 3
|
||||
---
|
||||
[
|
||||
{
|
||||
"Sequence": [
|
||||
{
|
||||
"Literal": 1
|
||||
},
|
||||
{
|
||||
"Literal": 2
|
||||
},
|
||||
{
|
||||
"Literal": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
/ abc / gim;
|
||||
---
|
||||
[
|
||||
{
|
||||
"Literal": "/ abc / gim"
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
if (0)
|
||||
1;
|
||||
---
|
||||
[
|
||||
{
|
||||
"If": {
|
||||
"Consequent": {
|
||||
"Literal": 1
|
||||
},
|
||||
"Test": {
|
||||
"Literal": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
0+function(){
|
||||
return;
|
||||
}
|
||||
---
|
||||
[
|
||||
{
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"Literal": 0
|
||||
},
|
||||
"Operator": "+",
|
||||
"Right": {
|
||||
"Function": {
|
||||
"BlockStatement": [
|
||||
{
|
||||
"Return": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
xyzzy // Ignore it
|
||||
// Ignore this
|
||||
// And this
|
||||
/* And all..
|
||||
|
||||
|
||||
|
||||
... of this!
|
||||
*/
|
||||
"Nothing happens."
|
||||
// And finally this
|
||||
---
|
||||
[
|
||||
{
|
||||
"Identifier": "xyzzy"
|
||||
},
|
||||
{
|
||||
"Literal": "\"Nothing happens.\""
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
((x & (x = 1)) !== 0)
|
||||
---
|
||||
[
|
||||
{
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"Identifier": "x"
|
||||
},
|
||||
"Operator": "\u0026",
|
||||
"Right": {
|
||||
"Assign": {
|
||||
"Left": {
|
||||
"Identifier": "x"
|
||||
},
|
||||
"Right": {
|
||||
"Literal": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Operator": "!==",
|
||||
"Right": {
|
||||
"Literal": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
{ abc: 'def' }
|
||||
---
|
||||
[
|
||||
{
|
||||
"BlockStatement": [
|
||||
{
|
||||
"Label": {
|
||||
"Name": "abc",
|
||||
"Statement": {
|
||||
"Literal": "'def'"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
// This is not an object, this is a string literal with a label!
|
||||
({ abc: 'def' })
|
||||
---
|
||||
[
|
||||
{
|
||||
"Object": [
|
||||
{
|
||||
"Key": "abc",
|
||||
"Value": {
|
||||
"Literal": "'def'"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
[,]
|
||||
---
|
||||
[
|
||||
{
|
||||
"Array": [
|
||||
null
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
[,,]
|
||||
---
|
||||
[
|
||||
{
|
||||
"Array": [
|
||||
null,
|
||||
null
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
({ get abc() {} })
|
||||
---
|
||||
[
|
||||
{
|
||||
"Object": [
|
||||
{
|
||||
"Key": "abc",
|
||||
"Value": {
|
||||
"Function": {
|
||||
"BlockStatement": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
/abc/.source
|
||||
---
|
||||
[
|
||||
{
|
||||
"Dot": {
|
||||
"Left": {
|
||||
"Literal": "/abc/"
|
||||
},
|
||||
"Member": "source"
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
xyzzy
|
||||
|
||||
throw new TypeError("Nothing happens.")
|
||||
---
|
||||
[
|
||||
{
|
||||
"Identifier": "xyzzy"
|
||||
},
|
||||
{
|
||||
"Throw": {
|
||||
"New": {
|
||||
"ArgumentList": [
|
||||
{
|
||||
"Literal": "\"Nothing happens.\""
|
||||
}
|
||||
],
|
||||
"Callee": {
|
||||
"Identifier": "TypeError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
// When run, this will call a type error to be thrown
|
||||
// This is essentially the same as:
|
||||
//
|
||||
// var abc = 1(function(){})()
|
||||
//
|
||||
test(`
|
||||
var abc = 1
|
||||
(function(){
|
||||
})()
|
||||
---
|
||||
[
|
||||
{
|
||||
"Var": [
|
||||
[
|
||||
"abc",
|
||||
{
|
||||
"Call": {
|
||||
"ArgumentList": [],
|
||||
"Callee": {
|
||||
"Call": {
|
||||
"ArgumentList": [
|
||||
{
|
||||
"Function": {
|
||||
"BlockStatement": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"Callee": {
|
||||
"Literal": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
"use strict"
|
||||
---
|
||||
[
|
||||
{
|
||||
"Literal": "\"use strict\""
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
"use strict"
|
||||
abc = 1 + 2 + 11
|
||||
---
|
||||
[
|
||||
{
|
||||
"Literal": "\"use strict\""
|
||||
},
|
||||
{
|
||||
"Assign": {
|
||||
"Left": {
|
||||
"Identifier": "abc"
|
||||
},
|
||||
"Right": {
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"Literal": 1
|
||||
},
|
||||
"Operator": "+",
|
||||
"Right": {
|
||||
"Literal": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"Operator": "+",
|
||||
"Right": {
|
||||
"Literal": 11
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
abc = function() { 'use strict' }
|
||||
---
|
||||
[
|
||||
{
|
||||
"Assign": {
|
||||
"Left": {
|
||||
"Identifier": "abc"
|
||||
},
|
||||
"Right": {
|
||||
"Function": {
|
||||
"BlockStatement": [
|
||||
{
|
||||
"Literal": "'use strict'"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
for (var abc in def) {
|
||||
}
|
||||
---
|
||||
[
|
||||
{
|
||||
"ForIn": {
|
||||
"Body": {
|
||||
"BlockStatement": []
|
||||
},
|
||||
"Into": [
|
||||
"abc",
|
||||
null
|
||||
],
|
||||
"Source": {
|
||||
"Identifier": "def"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
test(`
|
||||
abc = {
|
||||
'"': "'",
|
||||
"'": '"',
|
||||
}
|
||||
---
|
||||
[
|
||||
{
|
||||
"Assign": {
|
||||
"Left": {
|
||||
"Identifier": "abc"
|
||||
},
|
||||
"Right": {
|
||||
"Object": [
|
||||
{
|
||||
"Key": "\"",
|
||||
"Value": {
|
||||
"Literal": "\"'\""
|
||||
}
|
||||
},
|
||||
{
|
||||
"Key": "'",
|
||||
"Value": {
|
||||
"Literal": "'\"'"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
return
|
||||
|
||||
test(`
|
||||
if (!abc && abc.jkl(def) && abc[0] === +abc[0] && abc.length < ghi) {
|
||||
}
|
||||
---
|
||||
[
|
||||
{
|
||||
"If": {
|
||||
"Consequent": {
|
||||
"BlockStatement": []
|
||||
},
|
||||
"Test": {
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"BinaryExpression": {
|
||||
"Left": null,
|
||||
"Operator": "\u0026\u0026",
|
||||
"Right": {
|
||||
"Call": {
|
||||
"ArgumentList": [
|
||||
{
|
||||
"Identifier": "def"
|
||||
}
|
||||
],
|
||||
"Callee": {
|
||||
"Dot": {
|
||||
"Left": {
|
||||
"Identifier": "abc"
|
||||
},
|
||||
"Member": "jkl"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Operator": "\u0026\u0026",
|
||||
"Right": {
|
||||
"BinaryExpression": {
|
||||
"Left": null,
|
||||
"Operator": "===",
|
||||
"Right": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Operator": "\u0026\u0026",
|
||||
"Right": {
|
||||
"BinaryExpression": {
|
||||
"Left": {
|
||||
"Dot": {
|
||||
"Left": {
|
||||
"Identifier": "abc"
|
||||
},
|
||||
"Member": "length"
|
||||
}
|
||||
},
|
||||
"Operator": "\u003c",
|
||||
"Right": {
|
||||
"Identifier": "ghi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
`)
|
||||
})
|
||||
}
|
||||
270
Godeps/_workspace/src/github.com/obscuren/otto/parser/parser.go
generated
vendored
270
Godeps/_workspace/src/github.com/obscuren/otto/parser/parser.go
generated
vendored
|
|
@ -1,270 +0,0 @@
|
|||
/*
|
||||
Package parser implements a parser for JavaScript.
|
||||
|
||||
import (
|
||||
"github.com/robertkrimen/otto/parser"
|
||||
)
|
||||
|
||||
Parse and return an AST
|
||||
|
||||
filename := "" // A filename is optional
|
||||
src := `
|
||||
// Sample xyzzy example
|
||||
(function(){
|
||||
if (3.14159 > 0) {
|
||||
console.log("Hello, World.");
|
||||
return;
|
||||
}
|
||||
|
||||
var xyzzy = NaN;
|
||||
console.log("Nothing happens.");
|
||||
return xyzzy;
|
||||
})();
|
||||
`
|
||||
|
||||
// Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
|
||||
program, err := parser.ParseFile(nil, filename, src, 0)
|
||||
|
||||
Warning
|
||||
|
||||
The parser and AST interfaces are still works-in-progress (particularly where
|
||||
node types are concerned) and may change in the future.
|
||||
|
||||
*/
|
||||
package parser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
"github.com/robertkrimen/otto/file"
|
||||
"github.com/robertkrimen/otto/token"
|
||||
)
|
||||
|
||||
// A Mode value is a set of flags (or 0). They control optional parser functionality.
|
||||
type Mode uint
|
||||
|
||||
const (
|
||||
IgnoreRegExpErrors Mode = 1 << iota // Ignore RegExp compatibility errors (allow backtracking)
|
||||
)
|
||||
|
||||
type _parser struct {
|
||||
filename string
|
||||
str string
|
||||
length int
|
||||
base int
|
||||
|
||||
chr rune // The current character
|
||||
chrOffset int // The offset of current character
|
||||
offset int // The offset after current character (may be greater than 1)
|
||||
|
||||
idx file.Idx // The index of token
|
||||
token token.Token // The token
|
||||
literal string // The literal of the token, if any
|
||||
|
||||
scope *_scope
|
||||
insertSemicolon bool // If we see a newline, then insert an implicit semicolon
|
||||
implicitSemicolon bool // An implicit semicolon exists
|
||||
|
||||
errors ErrorList
|
||||
|
||||
recover struct {
|
||||
// Scratch when trying to seek to the next statement, etc.
|
||||
idx file.Idx
|
||||
count int
|
||||
}
|
||||
|
||||
mode Mode
|
||||
}
|
||||
|
||||
func _newParser(filename, src string, base int) *_parser {
|
||||
return &_parser{
|
||||
chr: ' ', // This is set so we can start scanning by skipping whitespace
|
||||
str: src,
|
||||
length: len(src),
|
||||
base: base,
|
||||
}
|
||||
}
|
||||
|
||||
func newParser(filename, src string) *_parser {
|
||||
return _newParser(filename, src, 1)
|
||||
}
|
||||
|
||||
func ReadSource(filename string, src interface{}) ([]byte, error) {
|
||||
if src != nil {
|
||||
switch src := src.(type) {
|
||||
case string:
|
||||
return []byte(src), nil
|
||||
case []byte:
|
||||
return src, nil
|
||||
case *bytes.Buffer:
|
||||
if src != nil {
|
||||
return src.Bytes(), nil
|
||||
}
|
||||
case io.Reader:
|
||||
var bfr bytes.Buffer
|
||||
if _, err := io.Copy(&bfr, src); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bfr.Bytes(), nil
|
||||
}
|
||||
return nil, errors.New("invalid source")
|
||||
}
|
||||
return ioutil.ReadFile(filename)
|
||||
}
|
||||
|
||||
// ParseFile parses the source code of a single JavaScript/ECMAScript source file and returns
|
||||
// the corresponding ast.Program node.
|
||||
//
|
||||
// If fileSet == nil, ParseFile parses source without a FileSet.
|
||||
// If fileSet != nil, ParseFile first adds filename and src to fileSet.
|
||||
//
|
||||
// The filename argument is optional and is used for labelling errors, etc.
|
||||
//
|
||||
// src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST always be in UTF-8.
|
||||
//
|
||||
// // Parse some JavaScript, yielding a *ast.Program and/or an ErrorList
|
||||
// program, err := parser.ParseFile(nil, "", `if (abc > 1) {}`, 0)
|
||||
//
|
||||
func ParseFile(fileSet *file.FileSet, filename string, src interface{}, mode Mode) (*ast.Program, error) {
|
||||
str, err := ReadSource(filename, src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
{
|
||||
str := string(str)
|
||||
|
||||
base := 1
|
||||
if fileSet != nil {
|
||||
base = fileSet.AddFile(filename, str)
|
||||
}
|
||||
|
||||
parser := _newParser(filename, str, base)
|
||||
parser.mode = mode
|
||||
return parser.parse()
|
||||
}
|
||||
}
|
||||
|
||||
// ParseFunction parses a given parameter list and body as a function and returns the
|
||||
// corresponding ast.FunctionLiteral node.
|
||||
//
|
||||
// The parameter list, if any, should be a comma-separated list of identifiers.
|
||||
//
|
||||
func ParseFunction(parameterList, body string) (*ast.FunctionLiteral, error) {
|
||||
|
||||
src := "(function(" + parameterList + ") {\n" + body + "\n})"
|
||||
|
||||
parser := _newParser("", src, 1)
|
||||
program, err := parser.parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.FunctionLiteral), nil
|
||||
}
|
||||
|
||||
func (self *_parser) slice(idx0, idx1 file.Idx) string {
|
||||
from := int(idx0) - self.base
|
||||
to := int(idx1) - self.base
|
||||
if from >= 0 && to <= len(self.str) {
|
||||
return self.str[from:to]
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *_parser) parse() (*ast.Program, error) {
|
||||
self.next()
|
||||
program := self.parseProgram()
|
||||
if false {
|
||||
self.errors.Sort()
|
||||
}
|
||||
return program, self.errors.Err()
|
||||
}
|
||||
|
||||
func (self *_parser) next() {
|
||||
self.token, self.literal, self.idx = self.scan()
|
||||
}
|
||||
|
||||
func (self *_parser) optionalSemicolon() {
|
||||
if self.token == token.SEMICOLON {
|
||||
self.next()
|
||||
return
|
||||
}
|
||||
|
||||
if self.implicitSemicolon {
|
||||
self.implicitSemicolon = false
|
||||
return
|
||||
}
|
||||
|
||||
if self.token != token.EOF && self.token != token.RIGHT_BRACE {
|
||||
self.expect(token.SEMICOLON)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) semicolon() {
|
||||
if self.token != token.RIGHT_PARENTHESIS && self.token != token.RIGHT_BRACE {
|
||||
if self.implicitSemicolon {
|
||||
self.implicitSemicolon = false
|
||||
return
|
||||
}
|
||||
|
||||
self.expect(token.SEMICOLON)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) idxOf(offset int) file.Idx {
|
||||
return file.Idx(self.base + offset)
|
||||
}
|
||||
|
||||
func (self *_parser) expect(value token.Token) file.Idx {
|
||||
idx := self.idx
|
||||
if self.token != value {
|
||||
self.errorUnexpectedToken(self.token)
|
||||
}
|
||||
self.next()
|
||||
return idx
|
||||
}
|
||||
|
||||
func lineCount(str string) (int, int) {
|
||||
line, last := 0, -1
|
||||
pair := false
|
||||
for index, chr := range str {
|
||||
switch chr {
|
||||
case '\r':
|
||||
line += 1
|
||||
last = index
|
||||
pair = true
|
||||
continue
|
||||
case '\n':
|
||||
if !pair {
|
||||
line += 1
|
||||
}
|
||||
last = index
|
||||
case '\u2028', '\u2029':
|
||||
line += 1
|
||||
last = index + 2
|
||||
}
|
||||
pair = false
|
||||
}
|
||||
return line, last
|
||||
}
|
||||
|
||||
func (self *_parser) position(idx file.Idx) file.Position {
|
||||
position := file.Position{}
|
||||
offset := int(idx) - self.base
|
||||
str := self.str[:offset]
|
||||
position.Filename = self.filename
|
||||
line, last := lineCount(str)
|
||||
position.Line = 1 + line
|
||||
if last >= 0 {
|
||||
position.Column = offset - last
|
||||
} else {
|
||||
position.Column = 1 + len(str)
|
||||
}
|
||||
|
||||
return position
|
||||
}
|
||||
1004
Godeps/_workspace/src/github.com/obscuren/otto/parser/parser_test.go
generated
vendored
1004
Godeps/_workspace/src/github.com/obscuren/otto/parser/parser_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
358
Godeps/_workspace/src/github.com/obscuren/otto/parser/regexp.go
generated
vendored
358
Godeps/_workspace/src/github.com/obscuren/otto/parser/regexp.go
generated
vendored
|
|
@ -1,358 +0,0 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type _RegExp_parser struct {
|
||||
str string
|
||||
length int
|
||||
|
||||
chr rune // The current character
|
||||
chrOffset int // The offset of current character
|
||||
offset int // The offset after current character (may be greater than 1)
|
||||
|
||||
errors []error
|
||||
invalid bool // The input is an invalid JavaScript RegExp
|
||||
|
||||
goRegexp *bytes.Buffer
|
||||
}
|
||||
|
||||
// TransformRegExp transforms a JavaScript pattern into a Go "regexp" pattern.
|
||||
//
|
||||
// re2 (Go) cannot do backtracking, so the presence of a lookahead (?=) (?!) or
|
||||
// backreference (\1, \2, ...) will cause an error.
|
||||
//
|
||||
// re2 (Go) has a different definition for \s: [\t\n\f\r ].
|
||||
// The JavaScript definition, on the other hand, also includes \v, Unicode "Separator, Space", etc.
|
||||
//
|
||||
// If the pattern is invalid (not valid even in JavaScript), then this function
|
||||
// returns the empty string and an error.
|
||||
//
|
||||
// If the pattern is valid, but incompatible (contains a lookahead or backreference),
|
||||
// then this function returns the transformation (a non-empty string) AND an error.
|
||||
func TransformRegExp(pattern string) (string, error) {
|
||||
|
||||
if pattern == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// TODO If without \, if without (?=, (?!, then another shortcut
|
||||
|
||||
parser := _RegExp_parser{
|
||||
str: pattern,
|
||||
length: len(pattern),
|
||||
goRegexp: bytes.NewBuffer(make([]byte, 0, 3*len(pattern)/2)),
|
||||
}
|
||||
parser.read() // Pull in the first character
|
||||
parser.scan()
|
||||
var err error
|
||||
if len(parser.errors) > 0 {
|
||||
err = parser.errors[0]
|
||||
}
|
||||
if parser.invalid {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Might not be re2 compatible, but is still a valid JavaScript RegExp
|
||||
return parser.goRegexp.String(), err
|
||||
}
|
||||
|
||||
func (self *_RegExp_parser) scan() {
|
||||
for self.chr != -1 {
|
||||
switch self.chr {
|
||||
case '\\':
|
||||
self.read()
|
||||
self.scanEscape(false)
|
||||
case '(':
|
||||
self.pass()
|
||||
self.scanGroup()
|
||||
case '[':
|
||||
self.pass()
|
||||
self.scanBracket()
|
||||
case ')':
|
||||
self.error(-1, "Unmatched ')'")
|
||||
self.invalid = true
|
||||
self.pass()
|
||||
default:
|
||||
self.pass()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (...)
|
||||
func (self *_RegExp_parser) scanGroup() {
|
||||
str := self.str[self.chrOffset:]
|
||||
if len(str) > 1 { // A possibility of (?= or (?!
|
||||
if str[0] == '?' {
|
||||
if str[1] == '=' || str[1] == '!' {
|
||||
self.error(-1, "re2: Invalid (%s) <lookahead>", self.str[self.chrOffset:self.chrOffset+2])
|
||||
}
|
||||
}
|
||||
}
|
||||
for self.chr != -1 && self.chr != ')' {
|
||||
switch self.chr {
|
||||
case '\\':
|
||||
self.read()
|
||||
self.scanEscape(false)
|
||||
case '(':
|
||||
self.pass()
|
||||
self.scanGroup()
|
||||
case '[':
|
||||
self.pass()
|
||||
self.scanBracket()
|
||||
default:
|
||||
self.pass()
|
||||
continue
|
||||
}
|
||||
}
|
||||
if self.chr != ')' {
|
||||
self.error(-1, "Unterminated group")
|
||||
self.invalid = true
|
||||
return
|
||||
}
|
||||
self.pass()
|
||||
}
|
||||
|
||||
// [...]
|
||||
func (self *_RegExp_parser) scanBracket() {
|
||||
for self.chr != -1 {
|
||||
if self.chr == ']' {
|
||||
break
|
||||
} else if self.chr == '\\' {
|
||||
self.read()
|
||||
self.scanEscape(true)
|
||||
continue
|
||||
}
|
||||
self.pass()
|
||||
}
|
||||
if self.chr != ']' {
|
||||
self.error(-1, "Unterminated character class")
|
||||
self.invalid = true
|
||||
return
|
||||
}
|
||||
self.pass()
|
||||
}
|
||||
|
||||
// \...
|
||||
func (self *_RegExp_parser) scanEscape(inClass bool) {
|
||||
offset := self.chrOffset
|
||||
|
||||
var length, base uint32
|
||||
switch self.chr {
|
||||
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7':
|
||||
var value int64
|
||||
size := 0
|
||||
for {
|
||||
digit := int64(digitValue(self.chr))
|
||||
if digit >= 8 {
|
||||
// Not a valid digit
|
||||
break
|
||||
}
|
||||
value = value*8 + digit
|
||||
self.read()
|
||||
size += 1
|
||||
}
|
||||
if size == 1 { // The number of characters read
|
||||
_, err := self.goRegexp.Write([]byte{'\\', byte(value) + '0'})
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
if value != 0 {
|
||||
// An invalid backreference
|
||||
self.error(-1, "re2: Invalid \\%d <backreference>", value)
|
||||
}
|
||||
return
|
||||
}
|
||||
tmp := []byte{'\\', 'x', '0', 0}
|
||||
if value >= 16 {
|
||||
tmp = tmp[0:2]
|
||||
} else {
|
||||
tmp = tmp[0:3]
|
||||
}
|
||||
tmp = strconv.AppendInt(tmp, value, 16)
|
||||
_, err := self.goRegexp.Write(tmp)
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
return
|
||||
|
||||
case '8', '9':
|
||||
size := 0
|
||||
for {
|
||||
digit := digitValue(self.chr)
|
||||
if digit >= 10 {
|
||||
// Not a valid digit
|
||||
break
|
||||
}
|
||||
self.read()
|
||||
size += 1
|
||||
}
|
||||
err := self.goRegexp.WriteByte('\\')
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
_, err = self.goRegexp.WriteString(self.str[offset:self.chrOffset])
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
self.error(-1, "re2: Invalid \\%s <backreference>", self.str[offset:self.chrOffset])
|
||||
return
|
||||
|
||||
case 'x':
|
||||
self.read()
|
||||
length, base = 2, 16
|
||||
|
||||
case 'u':
|
||||
self.read()
|
||||
length, base = 4, 16
|
||||
|
||||
case 'b':
|
||||
if inClass {
|
||||
_, err := self.goRegexp.Write([]byte{'\\', 'x', '0', '8'})
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
self.read()
|
||||
return
|
||||
}
|
||||
fallthrough
|
||||
|
||||
case 'B':
|
||||
fallthrough
|
||||
|
||||
case 'd', 'D', 's', 'S', 'w', 'W':
|
||||
// This is slightly broken, because ECMAScript
|
||||
// includes \v in \s, \S, while re2 does not
|
||||
fallthrough
|
||||
|
||||
case '\\':
|
||||
fallthrough
|
||||
|
||||
case 'f', 'n', 'r', 't', 'v':
|
||||
err := self.goRegexp.WriteByte('\\')
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
self.pass()
|
||||
return
|
||||
|
||||
case 'c':
|
||||
self.read()
|
||||
var value int64
|
||||
if 'a' <= self.chr && self.chr <= 'z' {
|
||||
value = int64(self.chr) - 'a' + 1
|
||||
} else if 'A' <= self.chr && self.chr <= 'Z' {
|
||||
value = int64(self.chr) - 'A' + 1
|
||||
} else {
|
||||
err := self.goRegexp.WriteByte('c')
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
tmp := []byte{'\\', 'x', '0', 0}
|
||||
if value >= 16 {
|
||||
tmp = tmp[0:2]
|
||||
} else {
|
||||
tmp = tmp[0:3]
|
||||
}
|
||||
tmp = strconv.AppendInt(tmp, value, 16)
|
||||
_, err := self.goRegexp.Write(tmp)
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
self.read()
|
||||
return
|
||||
|
||||
default:
|
||||
// $ is an identifier character, so we have to have
|
||||
// a special case for it here
|
||||
if self.chr == '$' || !isIdentifierPart(self.chr) {
|
||||
// A non-identifier character needs escaping
|
||||
err := self.goRegexp.WriteByte('\\')
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
} else {
|
||||
// Unescape the character for re2
|
||||
}
|
||||
self.pass()
|
||||
return
|
||||
}
|
||||
|
||||
// Otherwise, we're a \u.... or \x...
|
||||
valueOffset := self.chrOffset
|
||||
|
||||
var value uint32
|
||||
{
|
||||
length := length
|
||||
for ; length > 0; length-- {
|
||||
digit := uint32(digitValue(self.chr))
|
||||
if digit >= base {
|
||||
// Not a valid digit
|
||||
goto skip
|
||||
}
|
||||
value = value*base + digit
|
||||
self.read()
|
||||
}
|
||||
}
|
||||
|
||||
if length == 4 {
|
||||
_, err := self.goRegexp.Write([]byte{
|
||||
'\\',
|
||||
'x',
|
||||
'{',
|
||||
self.str[valueOffset+0],
|
||||
self.str[valueOffset+1],
|
||||
self.str[valueOffset+2],
|
||||
self.str[valueOffset+3],
|
||||
'}',
|
||||
})
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
} else if length == 2 {
|
||||
_, err := self.goRegexp.Write([]byte{
|
||||
'\\',
|
||||
'x',
|
||||
self.str[valueOffset+0],
|
||||
self.str[valueOffset+1],
|
||||
})
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
} else {
|
||||
// Should never, ever get here...
|
||||
self.error(-1, "re2: Illegal branch in scanEscape")
|
||||
goto skip
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
skip:
|
||||
_, err := self.goRegexp.WriteString(self.str[offset:self.chrOffset])
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_RegExp_parser) pass() {
|
||||
if self.chr != -1 {
|
||||
_, err := self.goRegexp.WriteRune(self.chr)
|
||||
if err != nil {
|
||||
self.errors = append(self.errors, err)
|
||||
}
|
||||
}
|
||||
self.read()
|
||||
}
|
||||
|
||||
// TODO Better error reporting, use the offset, etc.
|
||||
func (self *_RegExp_parser) error(offset int, msg string, msgValues ...interface{}) error {
|
||||
err := fmt.Errorf(msg, msgValues...)
|
||||
self.errors = append(self.errors, err)
|
||||
return err
|
||||
}
|
||||
149
Godeps/_workspace/src/github.com/obscuren/otto/parser/regexp_test.go
generated
vendored
149
Godeps/_workspace/src/github.com/obscuren/otto/parser/regexp_test.go
generated
vendored
|
|
@ -1,149 +0,0 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRegExp(t *testing.T) {
|
||||
tt(t, func() {
|
||||
{
|
||||
// err
|
||||
test := func(input string, expect interface{}) {
|
||||
_, err := TransformRegExp(input)
|
||||
is(err, expect)
|
||||
}
|
||||
|
||||
test("[", "Unterminated character class")
|
||||
|
||||
test("(", "Unterminated group")
|
||||
|
||||
test("(?=)", "re2: Invalid (?=) <lookahead>")
|
||||
|
||||
test("(?=)", "re2: Invalid (?=) <lookahead>")
|
||||
|
||||
test("(?!)", "re2: Invalid (?!) <lookahead>")
|
||||
|
||||
// An error anyway
|
||||
test("(?=", "re2: Invalid (?=) <lookahead>")
|
||||
|
||||
test("\\1", "re2: Invalid \\1 <backreference>")
|
||||
|
||||
test("\\90", "re2: Invalid \\90 <backreference>")
|
||||
|
||||
test("\\9123456789", "re2: Invalid \\9123456789 <backreference>")
|
||||
|
||||
test("\\(?=)", "Unmatched ')'")
|
||||
|
||||
test(")", "Unmatched ')'")
|
||||
}
|
||||
|
||||
{
|
||||
// err
|
||||
test := func(input, expect string, expectErr interface{}) {
|
||||
output, err := TransformRegExp(input)
|
||||
is(output, expect)
|
||||
is(err, expectErr)
|
||||
}
|
||||
|
||||
test("(?!)", "(?!)", "re2: Invalid (?!) <lookahead>")
|
||||
|
||||
test(")", "", "Unmatched ')'")
|
||||
|
||||
test("(?!))", "", "re2: Invalid (?!) <lookahead>")
|
||||
|
||||
test("\\0", "\\0", nil)
|
||||
|
||||
test("\\1", "\\1", "re2: Invalid \\1 <backreference>")
|
||||
|
||||
test("\\9123456789", "\\9123456789", "re2: Invalid \\9123456789 <backreference>")
|
||||
}
|
||||
|
||||
{
|
||||
// err
|
||||
test := func(input string, expect string) {
|
||||
result, err := TransformRegExp(input)
|
||||
is(err, nil)
|
||||
if is(result, expect) {
|
||||
_, err := regexp.Compile(result)
|
||||
if !is(err, nil) {
|
||||
t.Log(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test("", "")
|
||||
|
||||
test("abc", "abc")
|
||||
|
||||
test(`\abc`, `abc`)
|
||||
|
||||
test(`\a\b\c`, `a\bc`)
|
||||
|
||||
test(`\x`, `x`)
|
||||
|
||||
test(`\c`, `c`)
|
||||
|
||||
test(`\cA`, `\x01`)
|
||||
|
||||
test(`\cz`, `\x1a`)
|
||||
|
||||
test(`\ca`, `\x01`)
|
||||
|
||||
test(`\cj`, `\x0a`)
|
||||
|
||||
test(`\ck`, `\x0b`)
|
||||
|
||||
test(`\+`, `\+`)
|
||||
|
||||
test(`[\b]`, `[\x08]`)
|
||||
|
||||
test(`\u0z01\x\undefined`, `u0z01xundefined`)
|
||||
|
||||
test(`\\|'|\r|\n|\t|\u2028|\u2029`, `\\|'|\r|\n|\t|\x{2028}|\x{2029}`)
|
||||
|
||||
test("]", "]")
|
||||
|
||||
test("}", "}")
|
||||
|
||||
test("%", "%")
|
||||
|
||||
test("(%)", "(%)")
|
||||
|
||||
test("(?:[%\\s])", "(?:[%\\s])")
|
||||
|
||||
test("[[]", "[[]")
|
||||
|
||||
test("\\101", "\\x41")
|
||||
|
||||
test("\\51", "\\x29")
|
||||
|
||||
test("\\051", "\\x29")
|
||||
|
||||
test("\\175", "\\x7d")
|
||||
|
||||
test("\\04", "\\x04")
|
||||
|
||||
test(`<%([\s\S]+?)%>`, `<%([\s\S]+?)%>`)
|
||||
|
||||
test(`(.)^`, "(.)^")
|
||||
|
||||
test(`<%-([\s\S]+?)%>|<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$`, `<%-([\s\S]+?)%>|<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$`)
|
||||
|
||||
test(`\$`, `\$`)
|
||||
|
||||
test(`[G-b]`, `[G-b]`)
|
||||
|
||||
test(`[G-b\0]`, `[G-b\0]`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestTransformRegExp(t *testing.T) {
|
||||
tt(t, func() {
|
||||
pattern, err := TransformRegExp(`\s+abc\s+`)
|
||||
is(err, nil)
|
||||
is(pattern, `\s+abc\s+`)
|
||||
is(regexp.MustCompile(pattern).MatchString("\t abc def"), true)
|
||||
})
|
||||
}
|
||||
44
Godeps/_workspace/src/github.com/obscuren/otto/parser/scope.go
generated
vendored
44
Godeps/_workspace/src/github.com/obscuren/otto/parser/scope.go
generated
vendored
|
|
@ -1,44 +0,0 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
)
|
||||
|
||||
type _scope struct {
|
||||
outer *_scope
|
||||
allowIn bool
|
||||
inIteration bool
|
||||
inSwitch bool
|
||||
inFunction bool
|
||||
declarationList []ast.Declaration
|
||||
|
||||
labels []string
|
||||
}
|
||||
|
||||
func (self *_parser) openScope() {
|
||||
self.scope = &_scope{
|
||||
outer: self.scope,
|
||||
allowIn: true,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) closeScope() {
|
||||
self.scope = self.scope.outer
|
||||
}
|
||||
|
||||
func (self *_scope) declare(declaration ast.Declaration) {
|
||||
self.declarationList = append(self.declarationList, declaration)
|
||||
}
|
||||
|
||||
func (self *_scope) hasLabel(name string) bool {
|
||||
for _, label := range self.labels {
|
||||
if label == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if self.outer != nil && !self.inFunction {
|
||||
// Crossing a function boundary to look for a label is verboten
|
||||
return self.outer.hasLabel(name)
|
||||
}
|
||||
return false
|
||||
}
|
||||
662
Godeps/_workspace/src/github.com/obscuren/otto/parser/statement.go
generated
vendored
662
Godeps/_workspace/src/github.com/obscuren/otto/parser/statement.go
generated
vendored
|
|
@ -1,662 +0,0 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
"github.com/robertkrimen/otto/token"
|
||||
)
|
||||
|
||||
func (self *_parser) parseBlockStatement() *ast.BlockStatement {
|
||||
node := &ast.BlockStatement{}
|
||||
node.LeftBrace = self.expect(token.LEFT_BRACE)
|
||||
node.List = self.parseStatementList()
|
||||
node.RightBrace = self.expect(token.RIGHT_BRACE)
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseEmptyStatement() ast.Statement {
|
||||
idx := self.expect(token.SEMICOLON)
|
||||
return &ast.EmptyStatement{Semicolon: idx}
|
||||
}
|
||||
|
||||
func (self *_parser) parseStatementList() (list []ast.Statement) {
|
||||
for self.token != token.RIGHT_BRACE && self.token != token.EOF {
|
||||
list = append(list, self.parseStatement())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (self *_parser) parseStatement() ast.Statement {
|
||||
|
||||
if self.token == token.EOF {
|
||||
self.errorUnexpectedToken(self.token)
|
||||
return &ast.BadStatement{From: self.idx, To: self.idx + 1}
|
||||
}
|
||||
|
||||
switch self.token {
|
||||
case token.SEMICOLON:
|
||||
return self.parseEmptyStatement()
|
||||
case token.LEFT_BRACE:
|
||||
return self.parseBlockStatement()
|
||||
case token.IF:
|
||||
return self.parseIfStatement()
|
||||
case token.DO:
|
||||
return self.parseDoWhileStatement()
|
||||
case token.WHILE:
|
||||
return self.parseWhileStatement()
|
||||
case token.FOR:
|
||||
return self.parseForOrForInStatement()
|
||||
case token.BREAK:
|
||||
return self.parseBreakStatement()
|
||||
case token.CONTINUE:
|
||||
return self.parseContinueStatement()
|
||||
case token.DEBUGGER:
|
||||
return self.parseDebuggerStatement()
|
||||
case token.WITH:
|
||||
return self.parseWithStatement()
|
||||
case token.VAR:
|
||||
return self.parseVariableStatement()
|
||||
case token.FUNCTION:
|
||||
self.parseFunction(true)
|
||||
// FIXME
|
||||
return &ast.EmptyStatement{}
|
||||
case token.SWITCH:
|
||||
return self.parseSwitchStatement()
|
||||
case token.RETURN:
|
||||
return self.parseReturnStatement()
|
||||
case token.THROW:
|
||||
return self.parseThrowStatement()
|
||||
case token.TRY:
|
||||
return self.parseTryStatement()
|
||||
}
|
||||
|
||||
expression := self.parseExpression()
|
||||
|
||||
if identifier, isIdentifier := expression.(*ast.Identifier); isIdentifier && self.token == token.COLON {
|
||||
// LabelledStatement
|
||||
colon := self.idx
|
||||
self.next() // :
|
||||
label := identifier.Name
|
||||
for _, value := range self.scope.labels {
|
||||
if label == value {
|
||||
self.error(identifier.Idx0(), "Label '%s' already exists", label)
|
||||
}
|
||||
}
|
||||
self.scope.labels = append(self.scope.labels, label) // Push the label
|
||||
statement := self.parseStatement()
|
||||
self.scope.labels = self.scope.labels[:len(self.scope.labels)-1] // Pop the label
|
||||
return &ast.LabelledStatement{
|
||||
Label: identifier,
|
||||
Colon: colon,
|
||||
Statement: statement,
|
||||
}
|
||||
}
|
||||
|
||||
self.optionalSemicolon()
|
||||
|
||||
return &ast.ExpressionStatement{
|
||||
Expression: expression,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseTryStatement() ast.Statement {
|
||||
|
||||
node := &ast.TryStatement{
|
||||
Try: self.expect(token.TRY),
|
||||
Body: self.parseBlockStatement(),
|
||||
}
|
||||
|
||||
if self.token == token.CATCH {
|
||||
catch := self.idx
|
||||
self.next()
|
||||
self.expect(token.LEFT_PARENTHESIS)
|
||||
if self.token != token.IDENTIFIER {
|
||||
self.expect(token.IDENTIFIER)
|
||||
self.nextStatement()
|
||||
return &ast.BadStatement{From: catch, To: self.idx}
|
||||
} else {
|
||||
identifier := self.parseIdentifier()
|
||||
self.expect(token.RIGHT_PARENTHESIS)
|
||||
node.Catch = &ast.CatchStatement{
|
||||
Catch: catch,
|
||||
Parameter: identifier,
|
||||
Body: self.parseBlockStatement(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.token == token.FINALLY {
|
||||
self.next()
|
||||
node.Finally = self.parseBlockStatement()
|
||||
}
|
||||
|
||||
if node.Catch == nil && node.Finally == nil {
|
||||
self.error(node.Try, "Missing catch or finally after try")
|
||||
return &ast.BadStatement{From: node.Try, To: node.Body.Idx1()}
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseFunctionParameterList() *ast.ParameterList {
|
||||
opening := self.expect(token.LEFT_PARENTHESIS)
|
||||
var list []*ast.Identifier
|
||||
for self.token != token.RIGHT_PARENTHESIS && self.token != token.EOF {
|
||||
if self.token != token.IDENTIFIER {
|
||||
self.expect(token.IDENTIFIER)
|
||||
} else {
|
||||
list = append(list, self.parseIdentifier())
|
||||
}
|
||||
if self.token != token.RIGHT_PARENTHESIS {
|
||||
self.expect(token.COMMA)
|
||||
}
|
||||
}
|
||||
closing := self.expect(token.RIGHT_PARENTHESIS)
|
||||
|
||||
return &ast.ParameterList{
|
||||
Opening: opening,
|
||||
List: list,
|
||||
Closing: closing,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseParameterList() (list []string) {
|
||||
for self.token != token.EOF {
|
||||
if self.token != token.IDENTIFIER {
|
||||
self.expect(token.IDENTIFIER)
|
||||
}
|
||||
list = append(list, self.literal)
|
||||
self.next()
|
||||
if self.token != token.EOF {
|
||||
self.expect(token.COMMA)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (self *_parser) parseFunction(declaration bool) *ast.FunctionLiteral {
|
||||
|
||||
node := &ast.FunctionLiteral{
|
||||
Function: self.expect(token.FUNCTION),
|
||||
}
|
||||
|
||||
var name *ast.Identifier
|
||||
if self.token == token.IDENTIFIER {
|
||||
name = self.parseIdentifier()
|
||||
if declaration {
|
||||
self.scope.declare(&ast.FunctionDeclaration{
|
||||
Function: node,
|
||||
})
|
||||
}
|
||||
} else if declaration {
|
||||
// Use expect error handling
|
||||
self.expect(token.IDENTIFIER)
|
||||
}
|
||||
node.Name = name
|
||||
node.ParameterList = self.parseFunctionParameterList()
|
||||
self.parseFunctionBlock(node)
|
||||
node.Source = self.slice(node.Idx0(), node.Idx1())
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseFunctionBlock(node *ast.FunctionLiteral) {
|
||||
{
|
||||
self.openScope()
|
||||
inFunction := self.scope.inFunction
|
||||
self.scope.inFunction = true
|
||||
defer func() {
|
||||
self.scope.inFunction = inFunction
|
||||
self.closeScope()
|
||||
}()
|
||||
node.Body = self.parseBlockStatement()
|
||||
node.DeclarationList = self.scope.declarationList
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseDebuggerStatement() ast.Statement {
|
||||
idx := self.expect(token.DEBUGGER)
|
||||
|
||||
node := &ast.DebuggerStatement{
|
||||
Debugger: idx,
|
||||
}
|
||||
|
||||
self.semicolon()
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseReturnStatement() ast.Statement {
|
||||
idx := self.expect(token.RETURN)
|
||||
|
||||
if !self.scope.inFunction {
|
||||
self.error(idx, "Illegal return statement")
|
||||
self.nextStatement()
|
||||
return &ast.BadStatement{From: idx, To: self.idx}
|
||||
}
|
||||
|
||||
node := &ast.ReturnStatement{
|
||||
Return: idx,
|
||||
}
|
||||
|
||||
if !self.implicitSemicolon && self.token != token.SEMICOLON && self.token != token.RIGHT_BRACE && self.token != token.EOF {
|
||||
node.Argument = self.parseExpression()
|
||||
}
|
||||
|
||||
self.semicolon()
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseThrowStatement() ast.Statement {
|
||||
idx := self.expect(token.THROW)
|
||||
|
||||
if self.implicitSemicolon {
|
||||
if self.chr == -1 { // Hackish
|
||||
self.error(idx, "Unexpected end of input")
|
||||
} else {
|
||||
self.error(idx, "Illegal newline after throw")
|
||||
}
|
||||
self.nextStatement()
|
||||
return &ast.BadStatement{From: idx, To: self.idx}
|
||||
}
|
||||
|
||||
node := &ast.ThrowStatement{
|
||||
Argument: self.parseExpression(),
|
||||
}
|
||||
|
||||
self.semicolon()
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseSwitchStatement() ast.Statement {
|
||||
self.expect(token.SWITCH)
|
||||
self.expect(token.LEFT_PARENTHESIS)
|
||||
node := &ast.SwitchStatement{
|
||||
Discriminant: self.parseExpression(),
|
||||
Default: -1,
|
||||
}
|
||||
self.expect(token.RIGHT_PARENTHESIS)
|
||||
|
||||
self.expect(token.LEFT_BRACE)
|
||||
|
||||
inSwitch := self.scope.inSwitch
|
||||
self.scope.inSwitch = true
|
||||
defer func() {
|
||||
self.scope.inSwitch = inSwitch
|
||||
}()
|
||||
|
||||
for index := 0; self.token != token.EOF; index++ {
|
||||
if self.token == token.RIGHT_BRACE {
|
||||
self.next()
|
||||
break
|
||||
}
|
||||
|
||||
clause := self.parseCaseStatement()
|
||||
if clause.Test == nil {
|
||||
if node.Default != -1 {
|
||||
self.error(clause.Case, "Already saw a default in switch")
|
||||
}
|
||||
node.Default = index
|
||||
}
|
||||
node.Body = append(node.Body, clause)
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseWithStatement() ast.Statement {
|
||||
self.expect(token.WITH)
|
||||
self.expect(token.LEFT_PARENTHESIS)
|
||||
node := &ast.WithStatement{
|
||||
Object: self.parseExpression(),
|
||||
}
|
||||
self.expect(token.RIGHT_PARENTHESIS)
|
||||
|
||||
node.Body = self.parseStatement()
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseCaseStatement() *ast.CaseStatement {
|
||||
|
||||
node := &ast.CaseStatement{
|
||||
Case: self.idx,
|
||||
}
|
||||
if self.token == token.DEFAULT {
|
||||
self.next()
|
||||
} else {
|
||||
self.expect(token.CASE)
|
||||
node.Test = self.parseExpression()
|
||||
}
|
||||
self.expect(token.COLON)
|
||||
|
||||
for {
|
||||
if self.token == token.EOF ||
|
||||
self.token == token.RIGHT_BRACE ||
|
||||
self.token == token.CASE ||
|
||||
self.token == token.DEFAULT {
|
||||
break
|
||||
}
|
||||
node.Consequent = append(node.Consequent, self.parseStatement())
|
||||
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseIterationStatement() ast.Statement {
|
||||
inIteration := self.scope.inIteration
|
||||
self.scope.inIteration = true
|
||||
defer func() {
|
||||
self.scope.inIteration = inIteration
|
||||
}()
|
||||
return self.parseStatement()
|
||||
}
|
||||
|
||||
func (self *_parser) parseForIn(into ast.Expression) *ast.ForInStatement {
|
||||
|
||||
// Already have consumed "<into> in"
|
||||
|
||||
source := self.parseExpression()
|
||||
self.expect(token.RIGHT_PARENTHESIS)
|
||||
|
||||
return &ast.ForInStatement{
|
||||
Into: into,
|
||||
Source: source,
|
||||
Body: self.parseIterationStatement(),
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseFor(initializer ast.Expression) *ast.ForStatement {
|
||||
|
||||
// Already have consumed "<initializer> ;"
|
||||
|
||||
var test, update ast.Expression
|
||||
|
||||
if self.token != token.SEMICOLON {
|
||||
test = self.parseExpression()
|
||||
}
|
||||
self.expect(token.SEMICOLON)
|
||||
|
||||
if self.token != token.RIGHT_PARENTHESIS {
|
||||
update = self.parseExpression()
|
||||
}
|
||||
self.expect(token.RIGHT_PARENTHESIS)
|
||||
|
||||
return &ast.ForStatement{
|
||||
Initializer: initializer,
|
||||
Test: test,
|
||||
Update: update,
|
||||
Body: self.parseIterationStatement(),
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseForOrForInStatement() ast.Statement {
|
||||
idx := self.expect(token.FOR)
|
||||
self.expect(token.LEFT_PARENTHESIS)
|
||||
|
||||
var left []ast.Expression
|
||||
|
||||
forIn := false
|
||||
if self.token != token.SEMICOLON {
|
||||
|
||||
allowIn := self.scope.allowIn
|
||||
self.scope.allowIn = false
|
||||
if self.token == token.VAR {
|
||||
var_ := self.idx
|
||||
self.next()
|
||||
list := self.parseVariableDeclarationList(var_)
|
||||
if len(list) == 1 && self.token == token.IN {
|
||||
self.next() // in
|
||||
forIn = true
|
||||
left = []ast.Expression{list[0]} // There is only one declaration
|
||||
} else {
|
||||
left = list
|
||||
}
|
||||
} else {
|
||||
left = append(left, self.parseExpression())
|
||||
if self.token == token.IN {
|
||||
self.next()
|
||||
forIn = true
|
||||
}
|
||||
}
|
||||
self.scope.allowIn = allowIn
|
||||
}
|
||||
|
||||
if forIn {
|
||||
switch left[0].(type) {
|
||||
case *ast.Identifier, *ast.DotExpression, *ast.BracketExpression, *ast.VariableExpression:
|
||||
// These are all acceptable
|
||||
default:
|
||||
self.error(idx, "Invalid left-hand side in for-in")
|
||||
self.nextStatement()
|
||||
return &ast.BadStatement{From: idx, To: self.idx}
|
||||
}
|
||||
return self.parseForIn(left[0])
|
||||
}
|
||||
|
||||
self.expect(token.SEMICOLON)
|
||||
return self.parseFor(&ast.SequenceExpression{Sequence: left})
|
||||
}
|
||||
|
||||
func (self *_parser) parseVariableStatement() *ast.VariableStatement {
|
||||
|
||||
idx := self.expect(token.VAR)
|
||||
|
||||
list := self.parseVariableDeclarationList(idx)
|
||||
self.semicolon()
|
||||
|
||||
return &ast.VariableStatement{
|
||||
Var: idx,
|
||||
List: list,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseDoWhileStatement() ast.Statement {
|
||||
inIteration := self.scope.inIteration
|
||||
self.scope.inIteration = true
|
||||
defer func() {
|
||||
self.scope.inIteration = inIteration
|
||||
}()
|
||||
|
||||
self.expect(token.DO)
|
||||
node := &ast.DoWhileStatement{}
|
||||
if self.token == token.LEFT_BRACE {
|
||||
node.Body = self.parseBlockStatement()
|
||||
} else {
|
||||
node.Body = self.parseStatement()
|
||||
}
|
||||
|
||||
self.expect(token.WHILE)
|
||||
self.expect(token.LEFT_PARENTHESIS)
|
||||
node.Test = self.parseExpression()
|
||||
self.expect(token.RIGHT_PARENTHESIS)
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseWhileStatement() ast.Statement {
|
||||
self.expect(token.WHILE)
|
||||
self.expect(token.LEFT_PARENTHESIS)
|
||||
node := &ast.WhileStatement{
|
||||
Test: self.parseExpression(),
|
||||
}
|
||||
self.expect(token.RIGHT_PARENTHESIS)
|
||||
node.Body = self.parseIterationStatement()
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseIfStatement() ast.Statement {
|
||||
self.expect(token.IF)
|
||||
self.expect(token.LEFT_PARENTHESIS)
|
||||
node := &ast.IfStatement{
|
||||
Test: self.parseExpression(),
|
||||
}
|
||||
self.expect(token.RIGHT_PARENTHESIS)
|
||||
|
||||
if self.token == token.LEFT_BRACE {
|
||||
node.Consequent = self.parseBlockStatement()
|
||||
} else {
|
||||
node.Consequent = self.parseStatement()
|
||||
}
|
||||
|
||||
if self.token == token.ELSE {
|
||||
self.next()
|
||||
node.Alternate = self.parseStatement()
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
func (self *_parser) parseSourceElement() ast.Statement {
|
||||
return self.parseStatement()
|
||||
}
|
||||
|
||||
func (self *_parser) parseSourceElements() []ast.Statement {
|
||||
body := []ast.Statement(nil)
|
||||
|
||||
for {
|
||||
if self.token != token.STRING {
|
||||
break
|
||||
}
|
||||
|
||||
body = append(body, self.parseSourceElement())
|
||||
}
|
||||
|
||||
for self.token != token.EOF {
|
||||
body = append(body, self.parseSourceElement())
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (self *_parser) parseProgram() *ast.Program {
|
||||
self.openScope()
|
||||
defer self.closeScope()
|
||||
return &ast.Program{
|
||||
Body: self.parseSourceElements(),
|
||||
DeclarationList: self.scope.declarationList,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_parser) parseBreakStatement() ast.Statement {
|
||||
idx := self.expect(token.BREAK)
|
||||
semicolon := self.implicitSemicolon
|
||||
if self.token == token.SEMICOLON {
|
||||
semicolon = true
|
||||
self.next()
|
||||
}
|
||||
|
||||
if semicolon || self.token == token.RIGHT_BRACE {
|
||||
self.implicitSemicolon = false
|
||||
if !self.scope.inIteration && !self.scope.inSwitch {
|
||||
goto illegal
|
||||
}
|
||||
return &ast.BranchStatement{
|
||||
Idx: idx,
|
||||
Token: token.BREAK,
|
||||
}
|
||||
}
|
||||
|
||||
if self.token == token.IDENTIFIER {
|
||||
identifier := self.parseIdentifier()
|
||||
if !self.scope.hasLabel(identifier.Name) {
|
||||
self.error(idx, "Undefined label '%s'", identifier.Name)
|
||||
return &ast.BadStatement{From: idx, To: identifier.Idx1()}
|
||||
}
|
||||
self.semicolon()
|
||||
return &ast.BranchStatement{
|
||||
Idx: idx,
|
||||
Token: token.BREAK,
|
||||
Label: identifier,
|
||||
}
|
||||
}
|
||||
|
||||
self.expect(token.IDENTIFIER)
|
||||
|
||||
illegal:
|
||||
self.error(idx, "Illegal break statement")
|
||||
self.nextStatement()
|
||||
return &ast.BadStatement{From: idx, To: self.idx}
|
||||
}
|
||||
|
||||
func (self *_parser) parseContinueStatement() ast.Statement {
|
||||
idx := self.expect(token.CONTINUE)
|
||||
semicolon := self.implicitSemicolon
|
||||
if self.token == token.SEMICOLON {
|
||||
semicolon = true
|
||||
self.next()
|
||||
}
|
||||
|
||||
if semicolon || self.token == token.RIGHT_BRACE {
|
||||
self.implicitSemicolon = false
|
||||
if !self.scope.inIteration {
|
||||
goto illegal
|
||||
}
|
||||
return &ast.BranchStatement{
|
||||
Idx: idx,
|
||||
Token: token.CONTINUE,
|
||||
}
|
||||
}
|
||||
|
||||
if self.token == token.IDENTIFIER {
|
||||
identifier := self.parseIdentifier()
|
||||
if !self.scope.hasLabel(identifier.Name) {
|
||||
self.error(idx, "Undefined label '%s'", identifier.Name)
|
||||
return &ast.BadStatement{From: idx, To: identifier.Idx1()}
|
||||
}
|
||||
if !self.scope.inIteration {
|
||||
goto illegal
|
||||
}
|
||||
self.semicolon()
|
||||
return &ast.BranchStatement{
|
||||
Idx: idx,
|
||||
Token: token.CONTINUE,
|
||||
Label: identifier,
|
||||
}
|
||||
}
|
||||
|
||||
self.expect(token.IDENTIFIER)
|
||||
|
||||
illegal:
|
||||
self.error(idx, "Illegal continue statement")
|
||||
self.nextStatement()
|
||||
return &ast.BadStatement{From: idx, To: self.idx}
|
||||
}
|
||||
|
||||
// Find the next statement after an error (recover)
|
||||
func (self *_parser) nextStatement() {
|
||||
for {
|
||||
switch self.token {
|
||||
case token.BREAK, token.CONTINUE,
|
||||
token.FOR, token.IF, token.RETURN, token.SWITCH,
|
||||
token.VAR, token.DO, token.TRY, token.WITH,
|
||||
token.WHILE, token.THROW, token.CATCH, token.FINALLY:
|
||||
// Return only if parser made some progress since last
|
||||
// sync or if it has not reached 10 next calls without
|
||||
// progress. Otherwise consume at least one token to
|
||||
// avoid an endless parser loop
|
||||
if self.idx == self.recover.idx && self.recover.count < 10 {
|
||||
self.recover.count++
|
||||
return
|
||||
}
|
||||
if self.idx > self.recover.idx {
|
||||
self.recover.idx = self.idx
|
||||
self.recover.count = 0
|
||||
return
|
||||
}
|
||||
// Reaching here indicates a parser bug, likely an
|
||||
// incorrect token list in this function, but it only
|
||||
// leads to skipping of possibly correct code if a
|
||||
// previous error is present, and thus is preferred
|
||||
// over a non-terminating parse.
|
||||
case token.EOF:
|
||||
return
|
||||
}
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
51
Godeps/_workspace/src/github.com/obscuren/otto/registry/README.markdown
generated
vendored
51
Godeps/_workspace/src/github.com/obscuren/otto/registry/README.markdown
generated
vendored
|
|
@ -1,51 +0,0 @@
|
|||
# registry
|
||||
--
|
||||
import "github.com/robertkrimen/otto/registry"
|
||||
|
||||
Package registry is an expirmental package to facillitate altering the otto
|
||||
runtime via import.
|
||||
|
||||
This interface can change at any time.
|
||||
|
||||
## Usage
|
||||
|
||||
#### func Apply
|
||||
|
||||
```go
|
||||
func Apply(callback func(Entry))
|
||||
```
|
||||
|
||||
#### type Entry
|
||||
|
||||
```go
|
||||
type Entry struct {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### func Register
|
||||
|
||||
```go
|
||||
func Register(source func() string) *Entry
|
||||
```
|
||||
|
||||
#### func (*Entry) Disable
|
||||
|
||||
```go
|
||||
func (self *Entry) Disable()
|
||||
```
|
||||
|
||||
#### func (*Entry) Enable
|
||||
|
||||
```go
|
||||
func (self *Entry) Enable()
|
||||
```
|
||||
|
||||
#### func (Entry) Source
|
||||
|
||||
```go
|
||||
func (self Entry) Source() string
|
||||
```
|
||||
|
||||
--
|
||||
**godocdown** http://github.com/robertkrimen/godocdown
|
||||
47
Godeps/_workspace/src/github.com/obscuren/otto/registry/registry.go
generated
vendored
47
Godeps/_workspace/src/github.com/obscuren/otto/registry/registry.go
generated
vendored
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
Package registry is an expirmental package to facillitate altering the otto runtime via import.
|
||||
|
||||
This interface can change at any time.
|
||||
*/
|
||||
package registry
|
||||
|
||||
var registry []*Entry = make([]*Entry, 0)
|
||||
|
||||
type Entry struct {
|
||||
active bool
|
||||
source func() string
|
||||
}
|
||||
|
||||
func newEntry(source func() string) *Entry {
|
||||
return &Entry{
|
||||
active: true,
|
||||
source: source,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Entry) Enable() {
|
||||
self.active = true
|
||||
}
|
||||
|
||||
func (self *Entry) Disable() {
|
||||
self.active = false
|
||||
}
|
||||
|
||||
func (self Entry) Source() string {
|
||||
return self.source()
|
||||
}
|
||||
|
||||
func Apply(callback func(Entry)) {
|
||||
for _, entry := range registry {
|
||||
if !entry.active {
|
||||
continue
|
||||
}
|
||||
callback(*entry)
|
||||
}
|
||||
}
|
||||
|
||||
func Register(source func() string) *Entry {
|
||||
entry := newEntry(source)
|
||||
registry = append(registry, entry)
|
||||
return entry
|
||||
}
|
||||
2
Godeps/_workspace/src/github.com/obscuren/otto/token/Makefile
generated
vendored
2
Godeps/_workspace/src/github.com/obscuren/otto/token/Makefile
generated
vendored
|
|
@ -1,2 +0,0 @@
|
|||
token_const.go: tokenfmt
|
||||
./$^ | gofmt > $@
|
||||
171
Godeps/_workspace/src/github.com/obscuren/otto/token/README.markdown
generated
vendored
171
Godeps/_workspace/src/github.com/obscuren/otto/token/README.markdown
generated
vendored
|
|
@ -1,171 +0,0 @@
|
|||
# token
|
||||
--
|
||||
import "github.com/robertkrimen/otto/token"
|
||||
|
||||
Package token defines constants representing the lexical tokens of JavaScript
|
||||
(ECMA5).
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
const (
|
||||
ILLEGAL
|
||||
EOF
|
||||
COMMENT
|
||||
KEYWORD
|
||||
|
||||
STRING
|
||||
BOOLEAN
|
||||
NULL
|
||||
NUMBER
|
||||
IDENTIFIER
|
||||
|
||||
PLUS // +
|
||||
MINUS // -
|
||||
MULTIPLY // *
|
||||
SLASH // /
|
||||
REMAINDER // %
|
||||
|
||||
AND // &
|
||||
OR // |
|
||||
EXCLUSIVE_OR // ^
|
||||
SHIFT_LEFT // <<
|
||||
SHIFT_RIGHT // >>
|
||||
UNSIGNED_SHIFT_RIGHT // >>>
|
||||
AND_NOT // &^
|
||||
|
||||
ADD_ASSIGN // +=
|
||||
SUBTRACT_ASSIGN // -=
|
||||
MULTIPLY_ASSIGN // *=
|
||||
QUOTIENT_ASSIGN // /=
|
||||
REMAINDER_ASSIGN // %=
|
||||
|
||||
AND_ASSIGN // &=
|
||||
OR_ASSIGN // |=
|
||||
EXCLUSIVE_OR_ASSIGN // ^=
|
||||
SHIFT_LEFT_ASSIGN // <<=
|
||||
SHIFT_RIGHT_ASSIGN // >>=
|
||||
UNSIGNED_SHIFT_RIGHT_ASSIGN // >>>=
|
||||
AND_NOT_ASSIGN // &^=
|
||||
|
||||
LOGICAL_AND // &&
|
||||
LOGICAL_OR // ||
|
||||
INCREMENT // ++
|
||||
DECREMENT // --
|
||||
|
||||
EQUAL // ==
|
||||
STRICT_EQUAL // ===
|
||||
LESS // <
|
||||
GREATER // >
|
||||
ASSIGN // =
|
||||
NOT // !
|
||||
|
||||
BITWISE_NOT // ~
|
||||
|
||||
NOT_EQUAL // !=
|
||||
STRICT_NOT_EQUAL // !==
|
||||
LESS_OR_EQUAL // <=
|
||||
GREATER_OR_EQUAL // <=
|
||||
|
||||
LEFT_PARENTHESIS // (
|
||||
LEFT_BRACKET // [
|
||||
LEFT_BRACE // {
|
||||
COMMA // ,
|
||||
PERIOD // .
|
||||
|
||||
RIGHT_PARENTHESIS // )
|
||||
RIGHT_BRACKET // ]
|
||||
RIGHT_BRACE // }
|
||||
SEMICOLON // ;
|
||||
COLON // :
|
||||
QUESTION_MARK // ?
|
||||
|
||||
IF
|
||||
IN
|
||||
DO
|
||||
|
||||
VAR
|
||||
FOR
|
||||
NEW
|
||||
TRY
|
||||
|
||||
THIS
|
||||
ELSE
|
||||
CASE
|
||||
VOID
|
||||
WITH
|
||||
|
||||
WHILE
|
||||
BREAK
|
||||
CATCH
|
||||
THROW
|
||||
|
||||
RETURN
|
||||
TYPEOF
|
||||
DELETE
|
||||
SWITCH
|
||||
|
||||
DEFAULT
|
||||
FINALLY
|
||||
|
||||
FUNCTION
|
||||
CONTINUE
|
||||
DEBUGGER
|
||||
|
||||
INSTANCEOF
|
||||
)
|
||||
```
|
||||
|
||||
#### type Token
|
||||
|
||||
```go
|
||||
type Token int
|
||||
```
|
||||
|
||||
Token is the set of lexical tokens in JavaScript (ECMA5).
|
||||
|
||||
#### func IsKeyword
|
||||
|
||||
```go
|
||||
func IsKeyword(literal string) (Token, bool)
|
||||
```
|
||||
IsKeyword returns the keyword token if literal is a keyword, a KEYWORD token if
|
||||
the literal is a future keyword (const, let, class, super, ...), or 0 if the
|
||||
literal is not a keyword.
|
||||
|
||||
If the literal is a keyword, IsKeyword returns a second value indicating if the
|
||||
literal is considered a future keyword in strict-mode only.
|
||||
|
||||
7.6.1.2 Future Reserved Words:
|
||||
|
||||
const
|
||||
class
|
||||
enum
|
||||
export
|
||||
extends
|
||||
import
|
||||
super
|
||||
|
||||
7.6.1.2 Future Reserved Words (strict):
|
||||
|
||||
implements
|
||||
interface
|
||||
let
|
||||
package
|
||||
private
|
||||
protected
|
||||
public
|
||||
static
|
||||
|
||||
#### func (Token) String
|
||||
|
||||
```go
|
||||
func (tkn Token) String() string
|
||||
```
|
||||
String returns the string corresponding to the token. For operators, delimiters,
|
||||
and keywords the string is the actual token string (e.g., for the token PLUS,
|
||||
the String() is "+"). For all other tokens the string corresponds to the token
|
||||
name (e.g. for the token IDENTIFIER, the string is "IDENTIFIER").
|
||||
|
||||
--
|
||||
**godocdown** http://github.com/robertkrimen/godocdown
|
||||
116
Godeps/_workspace/src/github.com/obscuren/otto/token/token.go
generated
vendored
116
Godeps/_workspace/src/github.com/obscuren/otto/token/token.go
generated
vendored
|
|
@ -1,116 +0,0 @@
|
|||
// Package token defines constants representing the lexical tokens of JavaScript (ECMA5).
|
||||
package token
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Token is the set of lexical tokens in JavaScript (ECMA5).
|
||||
type Token int
|
||||
|
||||
// String returns the string corresponding to the token.
|
||||
// For operators, delimiters, and keywords the string is the actual
|
||||
// token string (e.g., for the token PLUS, the String() is
|
||||
// "+"). For all other tokens the string corresponds to the token
|
||||
// name (e.g. for the token IDENTIFIER, the string is "IDENTIFIER").
|
||||
//
|
||||
func (tkn Token) String() string {
|
||||
if 0 == tkn {
|
||||
return "UNKNOWN"
|
||||
}
|
||||
if tkn < Token(len(token2string)) {
|
||||
return token2string[tkn]
|
||||
}
|
||||
return "token(" + strconv.Itoa(int(tkn)) + ")"
|
||||
}
|
||||
|
||||
// This is not used for anything
|
||||
func (tkn Token) precedence(in bool) int {
|
||||
|
||||
switch tkn {
|
||||
case LOGICAL_OR:
|
||||
return 1
|
||||
|
||||
case LOGICAL_AND:
|
||||
return 2
|
||||
|
||||
case OR, OR_ASSIGN:
|
||||
return 3
|
||||
|
||||
case EXCLUSIVE_OR:
|
||||
return 4
|
||||
|
||||
case AND, AND_ASSIGN, AND_NOT, AND_NOT_ASSIGN:
|
||||
return 5
|
||||
|
||||
case EQUAL,
|
||||
NOT_EQUAL,
|
||||
STRICT_EQUAL,
|
||||
STRICT_NOT_EQUAL:
|
||||
return 6
|
||||
|
||||
case LESS, GREATER, LESS_OR_EQUAL, GREATER_OR_EQUAL, INSTANCEOF:
|
||||
return 7
|
||||
|
||||
case IN:
|
||||
if in {
|
||||
return 7
|
||||
}
|
||||
return 0
|
||||
|
||||
case SHIFT_LEFT, SHIFT_RIGHT, UNSIGNED_SHIFT_RIGHT:
|
||||
fallthrough
|
||||
case SHIFT_LEFT_ASSIGN, SHIFT_RIGHT_ASSIGN, UNSIGNED_SHIFT_RIGHT_ASSIGN:
|
||||
return 8
|
||||
|
||||
case PLUS, MINUS, ADD_ASSIGN, SUBTRACT_ASSIGN:
|
||||
return 9
|
||||
|
||||
case MULTIPLY, SLASH, REMAINDER, MULTIPLY_ASSIGN, QUOTIENT_ASSIGN, REMAINDER_ASSIGN:
|
||||
return 11
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type _keyword struct {
|
||||
token Token
|
||||
futureKeyword bool
|
||||
strict bool
|
||||
}
|
||||
|
||||
// IsKeyword returns the keyword token if literal is a keyword, a KEYWORD token
|
||||
// if the literal is a future keyword (const, let, class, super, ...), or 0 if the literal is not a keyword.
|
||||
//
|
||||
// If the literal is a keyword, IsKeyword returns a second value indicating if the literal
|
||||
// is considered a future keyword in strict-mode only.
|
||||
//
|
||||
// 7.6.1.2 Future Reserved Words:
|
||||
//
|
||||
// const
|
||||
// class
|
||||
// enum
|
||||
// export
|
||||
// extends
|
||||
// import
|
||||
// super
|
||||
//
|
||||
// 7.6.1.2 Future Reserved Words (strict):
|
||||
//
|
||||
// implements
|
||||
// interface
|
||||
// let
|
||||
// package
|
||||
// private
|
||||
// protected
|
||||
// public
|
||||
// static
|
||||
//
|
||||
func IsKeyword(literal string) (Token, bool) {
|
||||
if keyword, exists := keywordTable[literal]; exists {
|
||||
if keyword.futureKeyword {
|
||||
return KEYWORD, keyword.strict
|
||||
}
|
||||
return keyword.token, false
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
349
Godeps/_workspace/src/github.com/obscuren/otto/token/token_const.go
generated
vendored
349
Godeps/_workspace/src/github.com/obscuren/otto/token/token_const.go
generated
vendored
|
|
@ -1,349 +0,0 @@
|
|||
package token
|
||||
|
||||
const (
|
||||
_ Token = iota
|
||||
|
||||
ILLEGAL
|
||||
EOF
|
||||
COMMENT
|
||||
KEYWORD
|
||||
|
||||
STRING
|
||||
BOOLEAN
|
||||
NULL
|
||||
NUMBER
|
||||
IDENTIFIER
|
||||
|
||||
PLUS // +
|
||||
MINUS // -
|
||||
MULTIPLY // *
|
||||
SLASH // /
|
||||
REMAINDER // %
|
||||
|
||||
AND // &
|
||||
OR // |
|
||||
EXCLUSIVE_OR // ^
|
||||
SHIFT_LEFT // <<
|
||||
SHIFT_RIGHT // >>
|
||||
UNSIGNED_SHIFT_RIGHT // >>>
|
||||
AND_NOT // &^
|
||||
|
||||
ADD_ASSIGN // +=
|
||||
SUBTRACT_ASSIGN // -=
|
||||
MULTIPLY_ASSIGN // *=
|
||||
QUOTIENT_ASSIGN // /=
|
||||
REMAINDER_ASSIGN // %=
|
||||
|
||||
AND_ASSIGN // &=
|
||||
OR_ASSIGN // |=
|
||||
EXCLUSIVE_OR_ASSIGN // ^=
|
||||
SHIFT_LEFT_ASSIGN // <<=
|
||||
SHIFT_RIGHT_ASSIGN // >>=
|
||||
UNSIGNED_SHIFT_RIGHT_ASSIGN // >>>=
|
||||
AND_NOT_ASSIGN // &^=
|
||||
|
||||
LOGICAL_AND // &&
|
||||
LOGICAL_OR // ||
|
||||
INCREMENT // ++
|
||||
DECREMENT // --
|
||||
|
||||
EQUAL // ==
|
||||
STRICT_EQUAL // ===
|
||||
LESS // <
|
||||
GREATER // >
|
||||
ASSIGN // =
|
||||
NOT // !
|
||||
|
||||
BITWISE_NOT // ~
|
||||
|
||||
NOT_EQUAL // !=
|
||||
STRICT_NOT_EQUAL // !==
|
||||
LESS_OR_EQUAL // <=
|
||||
GREATER_OR_EQUAL // <=
|
||||
|
||||
LEFT_PARENTHESIS // (
|
||||
LEFT_BRACKET // [
|
||||
LEFT_BRACE // {
|
||||
COMMA // ,
|
||||
PERIOD // .
|
||||
|
||||
RIGHT_PARENTHESIS // )
|
||||
RIGHT_BRACKET // ]
|
||||
RIGHT_BRACE // }
|
||||
SEMICOLON // ;
|
||||
COLON // :
|
||||
QUESTION_MARK // ?
|
||||
|
||||
firstKeyword
|
||||
IF
|
||||
IN
|
||||
DO
|
||||
|
||||
VAR
|
||||
FOR
|
||||
NEW
|
||||
TRY
|
||||
|
||||
THIS
|
||||
ELSE
|
||||
CASE
|
||||
VOID
|
||||
WITH
|
||||
|
||||
WHILE
|
||||
BREAK
|
||||
CATCH
|
||||
THROW
|
||||
|
||||
RETURN
|
||||
TYPEOF
|
||||
DELETE
|
||||
SWITCH
|
||||
|
||||
DEFAULT
|
||||
FINALLY
|
||||
|
||||
FUNCTION
|
||||
CONTINUE
|
||||
DEBUGGER
|
||||
|
||||
INSTANCEOF
|
||||
lastKeyword
|
||||
)
|
||||
|
||||
var token2string = [...]string{
|
||||
ILLEGAL: "ILLEGAL",
|
||||
EOF: "EOF",
|
||||
COMMENT: "COMMENT",
|
||||
KEYWORD: "KEYWORD",
|
||||
STRING: "STRING",
|
||||
BOOLEAN: "BOOLEAN",
|
||||
NULL: "NULL",
|
||||
NUMBER: "NUMBER",
|
||||
IDENTIFIER: "IDENTIFIER",
|
||||
PLUS: "+",
|
||||
MINUS: "-",
|
||||
MULTIPLY: "*",
|
||||
SLASH: "/",
|
||||
REMAINDER: "%",
|
||||
AND: "&",
|
||||
OR: "|",
|
||||
EXCLUSIVE_OR: "^",
|
||||
SHIFT_LEFT: "<<",
|
||||
SHIFT_RIGHT: ">>",
|
||||
UNSIGNED_SHIFT_RIGHT: ">>>",
|
||||
AND_NOT: "&^",
|
||||
ADD_ASSIGN: "+=",
|
||||
SUBTRACT_ASSIGN: "-=",
|
||||
MULTIPLY_ASSIGN: "*=",
|
||||
QUOTIENT_ASSIGN: "/=",
|
||||
REMAINDER_ASSIGN: "%=",
|
||||
AND_ASSIGN: "&=",
|
||||
OR_ASSIGN: "|=",
|
||||
EXCLUSIVE_OR_ASSIGN: "^=",
|
||||
SHIFT_LEFT_ASSIGN: "<<=",
|
||||
SHIFT_RIGHT_ASSIGN: ">>=",
|
||||
UNSIGNED_SHIFT_RIGHT_ASSIGN: ">>>=",
|
||||
AND_NOT_ASSIGN: "&^=",
|
||||
LOGICAL_AND: "&&",
|
||||
LOGICAL_OR: "||",
|
||||
INCREMENT: "++",
|
||||
DECREMENT: "--",
|
||||
EQUAL: "==",
|
||||
STRICT_EQUAL: "===",
|
||||
LESS: "<",
|
||||
GREATER: ">",
|
||||
ASSIGN: "=",
|
||||
NOT: "!",
|
||||
BITWISE_NOT: "~",
|
||||
NOT_EQUAL: "!=",
|
||||
STRICT_NOT_EQUAL: "!==",
|
||||
LESS_OR_EQUAL: "<=",
|
||||
GREATER_OR_EQUAL: "<=",
|
||||
LEFT_PARENTHESIS: "(",
|
||||
LEFT_BRACKET: "[",
|
||||
LEFT_BRACE: "{",
|
||||
COMMA: ",",
|
||||
PERIOD: ".",
|
||||
RIGHT_PARENTHESIS: ")",
|
||||
RIGHT_BRACKET: "]",
|
||||
RIGHT_BRACE: "}",
|
||||
SEMICOLON: ";",
|
||||
COLON: ":",
|
||||
QUESTION_MARK: "?",
|
||||
IF: "if",
|
||||
IN: "in",
|
||||
DO: "do",
|
||||
VAR: "var",
|
||||
FOR: "for",
|
||||
NEW: "new",
|
||||
TRY: "try",
|
||||
THIS: "this",
|
||||
ELSE: "else",
|
||||
CASE: "case",
|
||||
VOID: "void",
|
||||
WITH: "with",
|
||||
WHILE: "while",
|
||||
BREAK: "break",
|
||||
CATCH: "catch",
|
||||
THROW: "throw",
|
||||
RETURN: "return",
|
||||
TYPEOF: "typeof",
|
||||
DELETE: "delete",
|
||||
SWITCH: "switch",
|
||||
DEFAULT: "default",
|
||||
FINALLY: "finally",
|
||||
FUNCTION: "function",
|
||||
CONTINUE: "continue",
|
||||
DEBUGGER: "debugger",
|
||||
INSTANCEOF: "instanceof",
|
||||
}
|
||||
|
||||
var keywordTable = map[string]_keyword{
|
||||
"if": _keyword{
|
||||
token: IF,
|
||||
},
|
||||
"in": _keyword{
|
||||
token: IN,
|
||||
},
|
||||
"do": _keyword{
|
||||
token: DO,
|
||||
},
|
||||
"var": _keyword{
|
||||
token: VAR,
|
||||
},
|
||||
"for": _keyword{
|
||||
token: FOR,
|
||||
},
|
||||
"new": _keyword{
|
||||
token: NEW,
|
||||
},
|
||||
"try": _keyword{
|
||||
token: TRY,
|
||||
},
|
||||
"this": _keyword{
|
||||
token: THIS,
|
||||
},
|
||||
"else": _keyword{
|
||||
token: ELSE,
|
||||
},
|
||||
"case": _keyword{
|
||||
token: CASE,
|
||||
},
|
||||
"void": _keyword{
|
||||
token: VOID,
|
||||
},
|
||||
"with": _keyword{
|
||||
token: WITH,
|
||||
},
|
||||
"while": _keyword{
|
||||
token: WHILE,
|
||||
},
|
||||
"break": _keyword{
|
||||
token: BREAK,
|
||||
},
|
||||
"catch": _keyword{
|
||||
token: CATCH,
|
||||
},
|
||||
"throw": _keyword{
|
||||
token: THROW,
|
||||
},
|
||||
"return": _keyword{
|
||||
token: RETURN,
|
||||
},
|
||||
"typeof": _keyword{
|
||||
token: TYPEOF,
|
||||
},
|
||||
"delete": _keyword{
|
||||
token: DELETE,
|
||||
},
|
||||
"switch": _keyword{
|
||||
token: SWITCH,
|
||||
},
|
||||
"default": _keyword{
|
||||
token: DEFAULT,
|
||||
},
|
||||
"finally": _keyword{
|
||||
token: FINALLY,
|
||||
},
|
||||
"function": _keyword{
|
||||
token: FUNCTION,
|
||||
},
|
||||
"continue": _keyword{
|
||||
token: CONTINUE,
|
||||
},
|
||||
"debugger": _keyword{
|
||||
token: DEBUGGER,
|
||||
},
|
||||
"instanceof": _keyword{
|
||||
token: INSTANCEOF,
|
||||
},
|
||||
"const": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
},
|
||||
"class": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
},
|
||||
"enum": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
},
|
||||
"export": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
},
|
||||
"extends": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
},
|
||||
"import": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
},
|
||||
"super": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
},
|
||||
"implements": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
strict: true,
|
||||
},
|
||||
"interface": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
strict: true,
|
||||
},
|
||||
"let": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
strict: true,
|
||||
},
|
||||
"package": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
strict: true,
|
||||
},
|
||||
"private": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
strict: true,
|
||||
},
|
||||
"protected": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
strict: true,
|
||||
},
|
||||
"public": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
strict: true,
|
||||
},
|
||||
"static": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
strict: true,
|
||||
},
|
||||
}
|
||||
222
Godeps/_workspace/src/github.com/obscuren/otto/token/tokenfmt
generated
vendored
222
Godeps/_workspace/src/github.com/obscuren/otto/token/tokenfmt
generated
vendored
|
|
@ -1,222 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my (%token, @order, @keywords);
|
||||
|
||||
{
|
||||
my $keywords;
|
||||
my @const;
|
||||
push @const, <<_END_;
|
||||
package token
|
||||
|
||||
const(
|
||||
_ Token = iota
|
||||
_END_
|
||||
|
||||
for (split m/\n/, <<_END_) {
|
||||
ILLEGAL
|
||||
EOF
|
||||
COMMENT
|
||||
KEYWORD
|
||||
|
||||
STRING
|
||||
BOOLEAN
|
||||
NULL
|
||||
NUMBER
|
||||
IDENTIFIER
|
||||
|
||||
PLUS +
|
||||
MINUS -
|
||||
MULTIPLY *
|
||||
SLASH /
|
||||
REMAINDER %
|
||||
|
||||
AND &
|
||||
OR |
|
||||
EXCLUSIVE_OR ^
|
||||
SHIFT_LEFT <<
|
||||
SHIFT_RIGHT >>
|
||||
UNSIGNED_SHIFT_RIGHT >>>
|
||||
AND_NOT &^
|
||||
|
||||
ADD_ASSIGN +=
|
||||
SUBTRACT_ASSIGN -=
|
||||
MULTIPLY_ASSIGN *=
|
||||
QUOTIENT_ASSIGN /=
|
||||
REMAINDER_ASSIGN %=
|
||||
|
||||
AND_ASSIGN &=
|
||||
OR_ASSIGN |=
|
||||
EXCLUSIVE_OR_ASSIGN ^=
|
||||
SHIFT_LEFT_ASSIGN <<=
|
||||
SHIFT_RIGHT_ASSIGN >>=
|
||||
UNSIGNED_SHIFT_RIGHT_ASSIGN >>>=
|
||||
AND_NOT_ASSIGN &^=
|
||||
|
||||
LOGICAL_AND &&
|
||||
LOGICAL_OR ||
|
||||
INCREMENT ++
|
||||
DECREMENT --
|
||||
|
||||
EQUAL ==
|
||||
STRICT_EQUAL ===
|
||||
LESS <
|
||||
GREATER >
|
||||
ASSIGN =
|
||||
NOT !
|
||||
|
||||
BITWISE_NOT ~
|
||||
|
||||
NOT_EQUAL !=
|
||||
STRICT_NOT_EQUAL !==
|
||||
LESS_OR_EQUAL <=
|
||||
GREATER_OR_EQUAL <=
|
||||
|
||||
LEFT_PARENTHESIS (
|
||||
LEFT_BRACKET [
|
||||
LEFT_BRACE {
|
||||
COMMA ,
|
||||
PERIOD .
|
||||
|
||||
RIGHT_PARENTHESIS )
|
||||
RIGHT_BRACKET ]
|
||||
RIGHT_BRACE }
|
||||
SEMICOLON ;
|
||||
COLON :
|
||||
QUESTION_MARK ?
|
||||
|
||||
firstKeyword
|
||||
IF
|
||||
IN
|
||||
DO
|
||||
|
||||
VAR
|
||||
FOR
|
||||
NEW
|
||||
TRY
|
||||
|
||||
THIS
|
||||
ELSE
|
||||
CASE
|
||||
VOID
|
||||
WITH
|
||||
|
||||
WHILE
|
||||
BREAK
|
||||
CATCH
|
||||
THROW
|
||||
|
||||
RETURN
|
||||
TYPEOF
|
||||
DELETE
|
||||
SWITCH
|
||||
|
||||
DEFAULT
|
||||
FINALLY
|
||||
|
||||
FUNCTION
|
||||
CONTINUE
|
||||
DEBUGGER
|
||||
|
||||
INSTANCEOF
|
||||
lastKeyword
|
||||
_END_
|
||||
chomp;
|
||||
|
||||
next if m/^\s*#/;
|
||||
|
||||
my ($name, $symbol) = m/(\w+)\s*(\S+)?/;
|
||||
|
||||
if (defined $symbol) {
|
||||
push @order, $name;
|
||||
push @const, "$name // $symbol";
|
||||
$token{$name} = $symbol;
|
||||
} elsif (defined $name) {
|
||||
$keywords ||= $name eq 'firstKeyword';
|
||||
|
||||
push @const, $name;
|
||||
#$const[-1] .= " Token = iota" if 2 == @const;
|
||||
if ($name =~ m/^([A-Z]+)/) {
|
||||
push @keywords, $name if $keywords;
|
||||
push @order, $name;
|
||||
if ($token{SEMICOLON}) {
|
||||
$token{$name} = lc $1;
|
||||
} else {
|
||||
$token{$name} = $name;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
push @const, "";
|
||||
}
|
||||
|
||||
}
|
||||
push @const, ")";
|
||||
print join "\n", @const, "";
|
||||
}
|
||||
|
||||
{
|
||||
print <<_END_;
|
||||
|
||||
var token2string = [...]string{
|
||||
_END_
|
||||
for my $name (@order) {
|
||||
print "$name: \"$token{$name}\",\n";
|
||||
}
|
||||
print <<_END_;
|
||||
}
|
||||
_END_
|
||||
|
||||
print <<_END_;
|
||||
|
||||
var keywordTable = map[string]_keyword{
|
||||
_END_
|
||||
for my $name (@keywords) {
|
||||
print <<_END_
|
||||
"@{[ lc $name ]}": _keyword{
|
||||
token: $name,
|
||||
},
|
||||
_END_
|
||||
}
|
||||
|
||||
for my $name (qw/
|
||||
const
|
||||
class
|
||||
enum
|
||||
export
|
||||
extends
|
||||
import
|
||||
super
|
||||
/) {
|
||||
print <<_END_
|
||||
"$name": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
},
|
||||
_END_
|
||||
}
|
||||
|
||||
for my $name (qw/
|
||||
implements
|
||||
interface
|
||||
let
|
||||
package
|
||||
private
|
||||
protected
|
||||
public
|
||||
static
|
||||
/) {
|
||||
print <<_END_
|
||||
"$name": _keyword{
|
||||
token: KEYWORD,
|
||||
futureKeyword: true,
|
||||
strict: true,
|
||||
},
|
||||
_END_
|
||||
}
|
||||
|
||||
print <<_END_;
|
||||
}
|
||||
_END_
|
||||
}
|
||||
9
Godeps/_workspace/src/github.com/obscuren/otto/type_error.go
generated
vendored
9
Godeps/_workspace/src/github.com/obscuren/otto/type_error.go
generated
vendored
|
|
@ -1,9 +0,0 @@
|
|||
package otto
|
||||
|
||||
func (runtime *_runtime) newErrorObject(message Value) *_object {
|
||||
self := runtime.newClassObject("Error")
|
||||
if message.IsDefined() {
|
||||
self.defineProperty("message", toValue_string(toString(message)), 0111, false)
|
||||
}
|
||||
return self
|
||||
}
|
||||
276
Godeps/_workspace/src/github.com/obscuren/otto/type_function.go
generated
vendored
276
Godeps/_workspace/src/github.com/obscuren/otto/type_function.go
generated
vendored
|
|
@ -1,276 +0,0 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type _functionObject struct {
|
||||
call _callFunction
|
||||
construct _constructFunction
|
||||
}
|
||||
|
||||
func (self _functionObject) source(object *_object) string {
|
||||
return self.call.Source(object)
|
||||
}
|
||||
|
||||
func (self0 _functionObject) clone(clone *_clone) _functionObject {
|
||||
return _functionObject{
|
||||
clone.callFunction(self0.call),
|
||||
self0.construct,
|
||||
}
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newNativeFunctionObject(name string, native _nativeFunction, length int) *_object {
|
||||
self := runtime.newClassObject("Function")
|
||||
self.value = _functionObject{
|
||||
call: newNativeCallFunction(native),
|
||||
construct: defaultConstructFunction,
|
||||
}
|
||||
self.defineProperty("length", toValue_int(length), 0000, false)
|
||||
return self
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newBoundFunctionObject(target *_object, this Value, argumentList []Value) *_object {
|
||||
self := runtime.newClassObject("Function")
|
||||
self.value = _functionObject{
|
||||
call: newBoundCallFunction(target, this, argumentList),
|
||||
construct: newBoundConstructFunction(target),
|
||||
}
|
||||
length := int(toInt32(target.get("length")))
|
||||
length -= len(argumentList)
|
||||
if length < 0 {
|
||||
length = 0
|
||||
}
|
||||
self.defineProperty("length", toValue_int(length), 0000, false)
|
||||
self.defineProperty("caller", UndefinedValue(), 0000, false) // TODO Should throw a TypeError
|
||||
self.defineProperty("arguments", UndefinedValue(), 0000, false) // TODO Should throw a TypeError
|
||||
return self
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newBoundFunction(target *_object, this Value, argumentList []Value) *_object {
|
||||
self := runtime.newBoundFunctionObject(target, this, argumentList)
|
||||
self.prototype = runtime.Global.FunctionPrototype
|
||||
prototype := runtime.newObject()
|
||||
self.defineProperty("prototype", toValue_object(prototype), 0100, false)
|
||||
prototype.defineProperty("constructor", toValue_object(self), 0100, false)
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *_object) functionValue() _functionObject {
|
||||
value, _ := self.value.(_functionObject)
|
||||
return value
|
||||
}
|
||||
|
||||
func (self *_object) Call(this Value, argumentList ...interface{}) Value {
|
||||
if self.functionValue().call == nil {
|
||||
panic(newTypeError("%v is not a function", toValue_object(self)))
|
||||
}
|
||||
return self.runtime.Call(self, this, self.runtime.toValueArray(argumentList...), false)
|
||||
// ... -> runtime -> self.Function.Call.Dispatch -> ...
|
||||
}
|
||||
|
||||
func (self *_object) Construct(this Value, argumentList ...interface{}) Value {
|
||||
function := self.functionValue()
|
||||
if function.call == nil {
|
||||
panic(newTypeError("%v is not a function", toValue_object(self)))
|
||||
}
|
||||
if function.construct == nil {
|
||||
panic(newTypeError("%v is not a constructor", toValue_object(self)))
|
||||
}
|
||||
return function.construct(self, this, self.runtime.toValueArray(argumentList...))
|
||||
}
|
||||
|
||||
func defaultConstructFunction(self *_object, this Value, argumentList []Value) Value {
|
||||
newObject := self.runtime.newObject()
|
||||
newObject.class = "Object"
|
||||
prototypeValue := self.get("prototype")
|
||||
if !prototypeValue.IsObject() {
|
||||
prototypeValue = toValue_object(self.runtime.Global.ObjectPrototype)
|
||||
}
|
||||
newObject.prototype = prototypeValue._object()
|
||||
newObjectValue := toValue_object(newObject)
|
||||
result := self.Call(newObjectValue, argumentList)
|
||||
if result.IsObject() {
|
||||
return result
|
||||
}
|
||||
return newObjectValue
|
||||
}
|
||||
|
||||
func (self *_object) callGet(this Value) Value {
|
||||
return self.runtime.Call(self, this, []Value(nil), false)
|
||||
}
|
||||
|
||||
func (self *_object) callSet(this Value, value Value) {
|
||||
self.runtime.Call(self, this, []Value{value}, false)
|
||||
}
|
||||
|
||||
// 15.3.5.3
|
||||
func (self *_object) HasInstance(of Value) bool {
|
||||
if self.functionValue().call == nil {
|
||||
// We should not have a HasInstance method
|
||||
panic(newTypeError())
|
||||
}
|
||||
if !of.IsObject() {
|
||||
return false
|
||||
}
|
||||
prototype := self.get("prototype")
|
||||
if !prototype.IsObject() {
|
||||
panic(newTypeError())
|
||||
}
|
||||
prototypeObject := prototype._object()
|
||||
|
||||
value := of._object().prototype
|
||||
for value != nil {
|
||||
if value == prototypeObject {
|
||||
return true
|
||||
}
|
||||
value = value.prototype
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type _nativeFunction func(FunctionCall) Value
|
||||
|
||||
// _constructFunction
|
||||
type _constructFunction func(*_object, Value, []Value) Value
|
||||
|
||||
// _callFunction
|
||||
type _callFunction interface {
|
||||
Dispatch(*_object, *_functionEnvironment, *_runtime, Value, []Value, bool) Value
|
||||
Source(*_object) string
|
||||
ScopeEnvironment() _environment
|
||||
clone(clone *_clone) _callFunction
|
||||
}
|
||||
|
||||
// _nativeCallFunction
|
||||
type _nativeCallFunction struct {
|
||||
name string
|
||||
function _nativeFunction
|
||||
}
|
||||
|
||||
func newNativeCallFunction(native _nativeFunction) _nativeCallFunction {
|
||||
return _nativeCallFunction{"", native}
|
||||
}
|
||||
|
||||
func (self _nativeCallFunction) Dispatch(_ *_object, _ *_functionEnvironment, runtime *_runtime, this Value, argumentList []Value, evalHint bool) Value {
|
||||
return self.function(FunctionCall{
|
||||
runtime: runtime,
|
||||
evalHint: evalHint,
|
||||
|
||||
This: this,
|
||||
ArgumentList: argumentList,
|
||||
Otto: runtime.Otto,
|
||||
})
|
||||
}
|
||||
|
||||
func (self _nativeCallFunction) ScopeEnvironment() _environment {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self _nativeCallFunction) Source(*_object) string {
|
||||
return fmt.Sprintf("function %s() { [native code] }", self.name)
|
||||
}
|
||||
|
||||
func (self0 _nativeCallFunction) clone(clone *_clone) _callFunction {
|
||||
return self0
|
||||
}
|
||||
|
||||
// _boundCallFunction
|
||||
type _boundCallFunction struct {
|
||||
target *_object
|
||||
this Value
|
||||
argumentList []Value
|
||||
}
|
||||
|
||||
func newBoundCallFunction(target *_object, this Value, argumentList []Value) *_boundCallFunction {
|
||||
self := &_boundCallFunction{
|
||||
target: target,
|
||||
this: this,
|
||||
argumentList: argumentList,
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
func (self _boundCallFunction) Dispatch(_ *_object, _ *_functionEnvironment, runtime *_runtime, this Value, argumentList []Value, _ bool) Value {
|
||||
argumentList = append(self.argumentList, argumentList...)
|
||||
return runtime.Call(self.target, self.this, argumentList, false)
|
||||
}
|
||||
|
||||
func (self _boundCallFunction) ScopeEnvironment() _environment {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self _boundCallFunction) Source(*_object) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self0 _boundCallFunction) clone(clone *_clone) _callFunction {
|
||||
return _boundCallFunction{
|
||||
target: clone.object(self0.target),
|
||||
this: clone.value(self0.this),
|
||||
argumentList: clone.valueArray(self0.argumentList),
|
||||
}
|
||||
}
|
||||
|
||||
func newBoundConstructFunction(target *_object) _constructFunction {
|
||||
// This is not exactly as described in 15.3.4.5.2, we let [[Call]] supply the
|
||||
// bound arguments, etc.
|
||||
return func(self *_object, this Value, argumentList []Value) Value {
|
||||
switch value := target.value.(type) {
|
||||
case _functionObject:
|
||||
return value.construct(self, this, argumentList)
|
||||
}
|
||||
panic(newTypeError())
|
||||
}
|
||||
}
|
||||
|
||||
// FunctionCall{}
|
||||
|
||||
// FunctionCall is an encapsulation of a JavaScript function call.
|
||||
type FunctionCall struct {
|
||||
runtime *_runtime
|
||||
_thisObject *_object
|
||||
evalHint bool
|
||||
|
||||
This Value
|
||||
ArgumentList []Value
|
||||
Otto *Otto
|
||||
}
|
||||
|
||||
// Argument will return the value of the argument at the given index.
|
||||
//
|
||||
// If no such argument exists, undefined is returned.
|
||||
func (self FunctionCall) Argument(index int) Value {
|
||||
return valueOfArrayIndex(self.ArgumentList, index)
|
||||
}
|
||||
|
||||
func (self FunctionCall) getArgument(index int) (Value, bool) {
|
||||
return getValueOfArrayIndex(self.ArgumentList, index)
|
||||
}
|
||||
|
||||
func (self FunctionCall) slice(index int) []Value {
|
||||
if index < len(self.ArgumentList) {
|
||||
return self.ArgumentList[index:]
|
||||
}
|
||||
return []Value{}
|
||||
}
|
||||
|
||||
func (self *FunctionCall) thisObject() *_object {
|
||||
if self._thisObject == nil {
|
||||
this := self.runtime.GetValue(self.This) // FIXME Is this right?
|
||||
self._thisObject = self.runtime.toObject(this)
|
||||
}
|
||||
return self._thisObject
|
||||
}
|
||||
|
||||
func (self *FunctionCall) thisClassObject(class string) *_object {
|
||||
thisObject := self.thisObject()
|
||||
if thisObject.class != class {
|
||||
panic(newTypeError())
|
||||
}
|
||||
return self._thisObject
|
||||
}
|
||||
|
||||
func (self FunctionCall) toObject(value Value) *_object {
|
||||
return self.runtime.toObject(value)
|
||||
}
|
||||
157
Godeps/_workspace/src/github.com/obscuren/otto/type_reference.go
generated
vendored
157
Godeps/_workspace/src/github.com/obscuren/otto/type_reference.go
generated
vendored
|
|
@ -1,157 +0,0 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
)
|
||||
|
||||
type _reference interface {
|
||||
GetBase() interface{} // GetBase
|
||||
GetName() string // GetReferencedName
|
||||
IsStrict() bool // IsStrictReference
|
||||
IsUnresolvable() bool // IsUnresolvableReference
|
||||
IsPropertyReference() bool // IsPropertyReference
|
||||
GetValue() Value // GetValue
|
||||
PutValue(Value) bool // PutValue
|
||||
Delete() bool
|
||||
}
|
||||
|
||||
// Reference
|
||||
|
||||
type _referenceDefault struct {
|
||||
name string
|
||||
strict bool
|
||||
}
|
||||
|
||||
func (self _referenceDefault) GetName() string {
|
||||
return self.name
|
||||
}
|
||||
|
||||
func (self _referenceDefault) IsStrict() bool {
|
||||
return self.strict
|
||||
}
|
||||
|
||||
// PropertyReference
|
||||
|
||||
type _propertyReference struct {
|
||||
_referenceDefault
|
||||
Base *_object
|
||||
}
|
||||
|
||||
func newPropertyReference(base *_object, name string, strict bool) *_propertyReference {
|
||||
return &_propertyReference{
|
||||
Base: base,
|
||||
_referenceDefault: _referenceDefault{
|
||||
name: name,
|
||||
strict: strict,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_propertyReference) GetBase() interface{} {
|
||||
return self.Base
|
||||
}
|
||||
|
||||
func (self *_propertyReference) IsUnresolvable() bool {
|
||||
return self.Base == nil
|
||||
}
|
||||
|
||||
func (self *_propertyReference) IsPropertyReference() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *_propertyReference) GetValue() Value {
|
||||
if self.Base == nil {
|
||||
panic(newReferenceError("notDefined", self.name))
|
||||
}
|
||||
return self.Base.get(self.name)
|
||||
}
|
||||
|
||||
func (self *_propertyReference) PutValue(value Value) bool {
|
||||
if self.Base == nil {
|
||||
return false
|
||||
}
|
||||
self.Base.put(self.name, value, self.IsStrict())
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *_propertyReference) Delete() bool {
|
||||
if self.Base == nil {
|
||||
// TODO Throw an error if strict
|
||||
return true
|
||||
}
|
||||
return self.Base.delete(self.name, self.IsStrict())
|
||||
}
|
||||
|
||||
// ArgumentReference
|
||||
|
||||
func newArgumentReference(base *_object, name string, strict bool) *_propertyReference {
|
||||
if base == nil {
|
||||
panic(hereBeDragons())
|
||||
}
|
||||
return newPropertyReference(base, name, strict)
|
||||
}
|
||||
|
||||
type _environmentReference struct {
|
||||
_referenceDefault
|
||||
Base _environment
|
||||
node ast.Node
|
||||
}
|
||||
|
||||
func newEnvironmentReference(base _environment, name string, strict bool, node ast.Node) *_environmentReference {
|
||||
return &_environmentReference{
|
||||
Base: base,
|
||||
_referenceDefault: _referenceDefault{
|
||||
name: name,
|
||||
strict: strict,
|
||||
},
|
||||
node: node,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_environmentReference) GetBase() interface{} {
|
||||
return self.Base
|
||||
}
|
||||
|
||||
func (self *_environmentReference) IsUnresolvable() bool {
|
||||
return self.Base == nil // The base (an environment) will never be nil
|
||||
}
|
||||
|
||||
func (self *_environmentReference) IsPropertyReference() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *_environmentReference) GetValue() Value {
|
||||
if self.Base == nil {
|
||||
// This should never be reached, but just in case
|
||||
}
|
||||
return self.Base.GetValue(self.name, self.IsStrict())
|
||||
}
|
||||
|
||||
func (self *_environmentReference) PutValue(value Value) bool {
|
||||
if self.Base == nil {
|
||||
// This should never be reached, but just in case
|
||||
return false
|
||||
}
|
||||
self.Base.SetValue(self.name, value, self.IsStrict())
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *_environmentReference) Delete() bool {
|
||||
if self.Base == nil {
|
||||
// This should never be reached, but just in case
|
||||
return false
|
||||
}
|
||||
return self.Base.DeleteBinding(self.name)
|
||||
}
|
||||
|
||||
// getIdentifierReference
|
||||
|
||||
func getIdentifierReference(environment _environment, name string, strict bool) _reference {
|
||||
if environment == nil {
|
||||
return newPropertyReference(nil, name, strict)
|
||||
}
|
||||
if environment.HasBinding(name) {
|
||||
return environment.newReference(name, strict)
|
||||
}
|
||||
return getIdentifierReference(environment.Outer(), name, strict)
|
||||
}
|
||||
|
|
@ -6,8 +6,8 @@ TESTS := \
|
|||
~
|
||||
|
||||
TEST := -v --run
|
||||
TEST := -v --run Test\($(subst $(eval) ,\|,$(TESTS))\)
|
||||
TEST := -v
|
||||
TEST := -v --run Test\($(subst $(eval) ,\|,$(TESTS))\)
|
||||
TEST := .
|
||||
|
||||
test: parser inline.go
|
||||
|
|
@ -60,7 +60,7 @@ Set a Go function
|
|||
|
||||
vm.Set("sayHello", func(call otto.FunctionCall) otto.Value {
|
||||
fmt.Printf("Hello, %s.\n", call.Argument(0).String())
|
||||
return otto.UndefinedValue()
|
||||
return otto.Value{}
|
||||
})
|
||||
|
||||
Set a Go function that returns something useful
|
||||
|
|
@ -139,7 +139,6 @@ For more information: http://github.com/robertkrimen/otto/tree/master/underscore
|
|||
The following are some limitations with otto:
|
||||
|
||||
* "use strict" will parse, but does nothing.
|
||||
* Error reporting needs to be improved.
|
||||
* The regular expression engine (re2/regexp) is not fully compatible with the ECMA5 specification.
|
||||
|
||||
|
||||
|
|
@ -205,16 +204,18 @@ the interrupt channel to do this:
|
|||
}
|
||||
fmt.Fprintf(os.Stderr, "Ran code successfully: %v\n", duration)
|
||||
}()
|
||||
|
||||
vm := otto.New()
|
||||
vm.Interrupt = make(chan func())
|
||||
vm.Interrupt = make(chan func(), 1) // The buffer prevents blocking
|
||||
|
||||
go func() {
|
||||
time.Sleep(2 * time.Second) // Stop after two seconds
|
||||
vm.Interrupt <- func() {
|
||||
panic(halt)
|
||||
}
|
||||
}()
|
||||
|
||||
vm.Run(unsafe) // Here be dragons (risky code)
|
||||
vm.Interrupt = nil
|
||||
}
|
||||
|
||||
Where is setTimeout/setInterval?
|
||||
|
|
@ -242,6 +243,36 @@ Here is some more discussion of the issue:
|
|||
var ErrVersion = errors.New("version mismatch")
|
||||
```
|
||||
|
||||
#### type Error
|
||||
|
||||
```go
|
||||
type Error struct {
|
||||
}
|
||||
```
|
||||
|
||||
An Error represents a runtime error, e.g. a TypeError, a ReferenceError, etc.
|
||||
|
||||
#### func (Error) Error
|
||||
|
||||
```go
|
||||
func (err Error) Error() string
|
||||
```
|
||||
Error returns a description of the error
|
||||
|
||||
TypeError: 'def' is not a function
|
||||
|
||||
#### func (Error) String
|
||||
|
||||
```go
|
||||
func (err Error) String() string
|
||||
```
|
||||
String returns a description of the error and a trace of where the error
|
||||
occurred.
|
||||
|
||||
TypeError: 'def' is not a function
|
||||
at xyz (<anonymous>:3:9)
|
||||
at <anonymous>:7:1/
|
||||
|
||||
#### type FunctionCall
|
||||
|
||||
```go
|
||||
|
|
@ -416,16 +447,16 @@ error if there was a problem during compilation.
|
|||
#### func (*Otto) Copy
|
||||
|
||||
```go
|
||||
func (self *Otto) Copy() *Otto
|
||||
func (in *Otto) Copy() *Otto
|
||||
```
|
||||
Copy will create a copy/clone of the runtime.
|
||||
|
||||
Copy is useful for saving some processing time when creating many similar
|
||||
runtimes.
|
||||
Copy is useful for saving some time when creating many similar runtimes.
|
||||
|
||||
This implementation is alpha-ish, and works by introspecting every part of the
|
||||
runtime and reallocating and then relinking everything back together. Please
|
||||
report if you notice any inadvertent sharing of data between copies.
|
||||
This method works by walking the original runtime and cloning each object,
|
||||
scope, stash, etc. into a new runtime.
|
||||
|
||||
Be on the lookout for memory leaks or inadvertent sharing of resources.
|
||||
|
||||
#### func (Otto) Get
|
||||
|
||||
|
|
@ -562,12 +593,10 @@ NullValue will return a Value representing null.
|
|||
func ToValue(value interface{}) (Value, error)
|
||||
```
|
||||
ToValue will convert an interface{} value to a value digestible by
|
||||
otto/JavaScript This function will not work for advanced types (struct, map,
|
||||
slice/array, etc.) and you probably should not use it.
|
||||
otto/JavaScript
|
||||
|
||||
ToValue may be deprecated and removed in the near future.
|
||||
|
||||
Try Otto.ToValue for a replacement.
|
||||
This function will not work for advanced types (struct, map, slice/array, etc.)
|
||||
and you should use Otto.ToValue instead.
|
||||
|
||||
#### func TrueValue
|
||||
|
||||
|
|
@ -630,15 +659,13 @@ func (self Value) Export() (interface{}, error)
|
|||
Export will attempt to convert the value to a Go representation and return it
|
||||
via an interface{} kind.
|
||||
|
||||
WARNING: The interface function will be changing soon to:
|
||||
Export returns an error, but it will always be nil. It is present for backwards
|
||||
compatibility.
|
||||
|
||||
Export() interface{}
|
||||
If a reasonable conversion is not possible, then the original value is returned.
|
||||
|
||||
If a reasonable conversion is not possible, then the original result is
|
||||
returned.
|
||||
|
||||
undefined -> otto.Value (UndefinedValue())
|
||||
null -> interface{}(nil)
|
||||
undefined -> nil (FIXME?: Should be Value{})
|
||||
null -> nil
|
||||
boolean -> bool
|
||||
number -> A number type (int, float32, uint64, ...)
|
||||
string -> string
|
||||
|
|
@ -55,7 +55,7 @@ func Test_issue13(t *testing.T) {
|
|||
t.Error(err)
|
||||
t.FailNow()
|
||||
}
|
||||
is(result.toString(), "Xyzzy,42,def,ghi")
|
||||
is(result.string(), "Xyzzy,42,def,ghi")
|
||||
|
||||
anything := struct {
|
||||
Abc interface{}
|
||||
|
|
@ -231,12 +231,12 @@ func Test_issue24(t *testing.T) {
|
|||
}
|
||||
|
||||
{
|
||||
vm.Set("abc", testStruct{Abc: true, Ghi: "Nothing happens."})
|
||||
vm.Set("abc", _abcStruct{Abc: true, Ghi: "Nothing happens."})
|
||||
value, err := vm.Get("abc")
|
||||
is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.(testStruct)
|
||||
value, valid := export.(_abcStruct)
|
||||
is(valid, true)
|
||||
|
||||
is(value.Abc, true)
|
||||
|
|
@ -245,12 +245,12 @@ func Test_issue24(t *testing.T) {
|
|||
}
|
||||
|
||||
{
|
||||
vm.Set("abc", &testStruct{Abc: true, Ghi: "Nothing happens."})
|
||||
vm.Set("abc", &_abcStruct{Abc: true, Ghi: "Nothing happens."})
|
||||
value, err := vm.Get("abc")
|
||||
is(err, nil)
|
||||
export, _ := value.Export()
|
||||
{
|
||||
value, valid := export.(*testStruct)
|
||||
value, valid := export.(*_abcStruct)
|
||||
is(valid, true)
|
||||
|
||||
is(value.Abc, true)
|
||||
|
|
@ -313,10 +313,22 @@ func Test_issue64(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func Test_issue73(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
vm.Set("abc", [4]int{3, 2, 1, 0})
|
||||
|
||||
test(`
|
||||
var def = [ 0, 1, 2, 3 ];
|
||||
JSON.stringify(def) + JSON.stringify(abc);
|
||||
`, "[0,1,2,3][3,2,1,0]")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_7_3_1(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test(`
|
||||
|
||||
eval("var test7_3_1\u2028abc = 66;");
|
||||
[ abc, typeof test7_3_1 ];
|
||||
`, "66,undefined")
|
||||
|
|
@ -502,3 +514,104 @@ def"
|
|||
`, "1,0,\t abc def,\t abc ")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_issue79(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
vm.Set("abc", []_abcStruct{
|
||||
{
|
||||
Ghi: "一",
|
||||
Def: 1,
|
||||
},
|
||||
{
|
||||
Def: 3,
|
||||
Ghi: "三",
|
||||
},
|
||||
{
|
||||
Def: 2,
|
||||
Ghi: "二",
|
||||
},
|
||||
{
|
||||
Def: 4,
|
||||
Ghi: "四",
|
||||
},
|
||||
})
|
||||
|
||||
test(`
|
||||
abc.sort(function(a,b){ return b.Def-a.Def });
|
||||
def = [];
|
||||
for (i = 0; i < abc.length; i++) {
|
||||
def.push(abc[i].String())
|
||||
}
|
||||
def;
|
||||
`, "四,三,二,一")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_issue80(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`
|
||||
JSON.stringify([
|
||||
1401868959,
|
||||
14018689591,
|
||||
140186895901,
|
||||
1401868959001,
|
||||
14018689590001,
|
||||
140186895900001,
|
||||
1401868959000001,
|
||||
1401868959000001.5,
|
||||
14018689590000001,
|
||||
140186895900000001,
|
||||
1401868959000000001,
|
||||
14018689590000000001,
|
||||
140186895900000000001,
|
||||
140186895900000000001.5
|
||||
]);
|
||||
`, "[1401868959,14018689591,140186895901,1401868959001,14018689590001,140186895900001,1401868959000001,1.4018689590000015e+15,14018689590000001,140186895900000001,1401868959000000001,1.401868959e+19,1.401868959e+20,1.401868959e+20]")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_issue87(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
test(`
|
||||
var def = 0;
|
||||
abc: {
|
||||
for (;;) {
|
||||
def = !1;
|
||||
break abc;
|
||||
}
|
||||
def = !0;
|
||||
}
|
||||
def;
|
||||
`, false)
|
||||
|
||||
_, err := vm.Run(`
|
||||
/*
|
||||
CryptoJS v3.1.2
|
||||
code.google.com/p/crypto-js
|
||||
(c) 2009-2013 by Jeff Mott. All rights reserved.
|
||||
code.google.com/p/crypto-js/wiki/License
|
||||
*/
|
||||
var CryptoJS=CryptoJS||function(h,s){var f={},g=f.lib={},q=function(){},m=g.Base={extend:function(a){q.prototype=this;var c=new q;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
|
||||
r=g.WordArray=m.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=s?c:4*a.length},toString:function(a){return(a||k).stringify(this)},concat:function(a){var c=this.words,d=a.words,b=this.sigBytes;a=a.sigBytes;this.clamp();if(b%4)for(var e=0;e<a;e++)c[b+e>>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535<d.length)for(e=0;e<a;e+=4)c[b+e>>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
|
||||
32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=m.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d<a;d+=4)c.push(4294967296*h.random()|0);return new r.init(c,a)}}),l=f.enc={},k=l.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++){var e=c[b>>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b+=2)d[b>>>3]|=parseInt(a.substr(b,
|
||||
2),16)<<24-4*(b%8);return new r.init(d,c/2)}},n=l.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++)d.push(String.fromCharCode(c[b>>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b++)d[b>>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new r.init(d,c)}},j=l.Utf8={stringify:function(a){try{return decodeURIComponent(escape(n.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return n.parse(unescape(encodeURIComponent(a)))}},
|
||||
u=g.BufferedBlockAlgorithm=m.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=j.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var g=0;g<a;g+=e)this._doProcessBlock(d,g);g=d.splice(0,a);c.sigBytes-=b}return new r.init(g,b)},clone:function(){var a=m.clone.call(this);
|
||||
a._data=this._data.clone();return a},_minBufferSize:0});g.Hasher=u.extend({cfg:m.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){u.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(c,d){return(new a.init(d)).finalize(c)}},_createHmacHelper:function(a){return function(c,d){return(new t.HMAC.init(a,
|
||||
d)).finalize(c)}}});var t=f.algo={};return f}(Math);
|
||||
(function(h){for(var s=CryptoJS,f=s.lib,g=f.WordArray,q=f.Hasher,f=s.algo,m=[],r=[],l=function(a){return 4294967296*(a-(a|0))|0},k=2,n=0;64>n;){var j;a:{j=k;for(var u=h.sqrt(j),t=2;t<=u;t++)if(!(j%t)){j=!1;break a}j=!0}j&&(8>n&&(m[n]=l(h.pow(k,0.5))),r[n]=l(h.pow(k,1/3)),n++);k++}var a=[],f=f.SHA256=q.extend({_doReset:function(){this._hash=new g.init(m.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],g=b[2],j=b[3],h=b[4],m=b[5],n=b[6],q=b[7],p=0;64>p;p++){if(16>p)a[p]=
|
||||
c[d+p]|0;else{var k=a[p-15],l=a[p-2];a[p]=((k<<25|k>>>7)^(k<<14|k>>>18)^k>>>3)+a[p-7]+((l<<15|l>>>17)^(l<<13|l>>>19)^l>>>10)+a[p-16]}k=q+((h<<26|h>>>6)^(h<<21|h>>>11)^(h<<7|h>>>25))+(h&m^~h&n)+r[p]+a[p];l=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&g^f&g);q=n;n=m;m=h;h=j+k|0;j=g;g=f;f=e;e=k+l|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+g|0;b[3]=b[3]+j|0;b[4]=b[4]+h|0;b[5]=b[5]+m|0;b[6]=b[6]+n|0;b[7]=b[7]+q|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes;
|
||||
d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=q.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=q._createHelper(f);s.HmacSHA256=q._createHmacHelper(f)})(Math);
|
||||
(function(){var h=CryptoJS,s=h.enc.Utf8;h.algo.HMAC=h.lib.Base.extend({init:function(f,g){f=this._hasher=new f.init;"string"==typeof g&&(g=s.parse(g));var h=f.blockSize,m=4*h;g.sigBytes>m&&(g=f.finalize(g));g.clamp();for(var r=this._oKey=g.clone(),l=this._iKey=g.clone(),k=r.words,n=l.words,j=0;j<h;j++)k[j]^=1549556828,n[j]^=909522486;r.sigBytes=l.sigBytes=m;this.reset()},reset:function(){var f=this._hasher;f.reset();f.update(this._iKey)},update:function(f){this._hasher.update(f);return this},finalize:function(f){var g=
|
||||
this._hasher;f=g.finalize(f);g.reset();return g.finalize(this._oKey.clone().concat(f))}})})();
|
||||
`)
|
||||
is(err, nil)
|
||||
|
||||
test(`CryptoJS.HmacSHA256("Message", "secret");`, "aa747c502a898200f9e4fa21bac68136f886a0e27aec70ba06daf2e2a5cb5597")
|
||||
})
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package otto
|
|||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/url"
|
||||
"regexp"
|
||||
|
|
@ -19,25 +18,26 @@ func builtinGlobal_eval(call FunctionCall) Value {
|
|||
return src
|
||||
}
|
||||
runtime := call.runtime
|
||||
program := runtime.cmpl_parseOrThrow(toString(src))
|
||||
if call.evalHint {
|
||||
runtime.EnterEvalExecutionContext(call)
|
||||
defer runtime.LeaveExecutionContext()
|
||||
program := runtime.cmpl_parseOrThrow(src.string())
|
||||
if !call.eval {
|
||||
// Not a direct call to eval, so we enter the global ExecutionContext
|
||||
runtime.enterGlobalScope()
|
||||
defer runtime.leaveScope()
|
||||
}
|
||||
returnValue := runtime.cmpl_evaluate_nodeProgram(program)
|
||||
returnValue := runtime.cmpl_evaluate_nodeProgram(program, true)
|
||||
if returnValue.isEmpty() {
|
||||
return UndefinedValue()
|
||||
return Value{}
|
||||
}
|
||||
return returnValue
|
||||
}
|
||||
|
||||
func builtinGlobal_isNaN(call FunctionCall) Value {
|
||||
value := toFloat(call.Argument(0))
|
||||
value := call.Argument(0).float64()
|
||||
return toValue_bool(math.IsNaN(value))
|
||||
}
|
||||
|
||||
func builtinGlobal_isFinite(call FunctionCall) Value {
|
||||
value := toFloat(call.Argument(0))
|
||||
value := call.Argument(0).float64()
|
||||
return toValue_bool(!math.IsNaN(value) && !math.IsInf(value, 0))
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ func digitValue(chr rune) int {
|
|||
}
|
||||
|
||||
func builtinGlobal_parseInt(call FunctionCall) Value {
|
||||
input := strings.TrimSpace(toString(call.Argument(0)))
|
||||
input := strings.TrimSpace(call.Argument(0).string())
|
||||
if len(input) == 0 {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -153,7 +153,7 @@ var parseFloat_matchValid = regexp.MustCompile(`[0-9eE\+\-\.]|Infinity`)
|
|||
|
||||
func builtinGlobal_parseFloat(call FunctionCall) Value {
|
||||
// Caveat emptor: This implementation does NOT match the specification
|
||||
input := strings.TrimSpace(toString(call.Argument(0)))
|
||||
input := strings.TrimSpace(call.Argument(0).string())
|
||||
if parseFloat_matchBadSpecial.MatchString(input) {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -185,7 +185,7 @@ func _builtinGlobal_encodeURI(call FunctionCall, escape *regexp.Regexp) Value {
|
|||
case []uint16:
|
||||
input = vl
|
||||
default:
|
||||
input = utf16.Encode([]rune(toString(value)))
|
||||
input = utf16.Encode([]rune(value.string()))
|
||||
}
|
||||
if len(input) == 0 {
|
||||
return toValue_string("")
|
||||
|
|
@ -197,18 +197,17 @@ func _builtinGlobal_encodeURI(call FunctionCall, escape *regexp.Regexp) Value {
|
|||
value := input[index]
|
||||
decode := utf16.Decode(input[index : index+1])
|
||||
if value >= 0xDC00 && value <= 0xDFFF {
|
||||
panic(newURIError("URI malformed"))
|
||||
panic(call.runtime.panicURIError("URI malformed"))
|
||||
}
|
||||
if value >= 0xD800 && value <= 0xDBFF {
|
||||
index += 1
|
||||
if index >= length {
|
||||
panic(newURIError("URI malformed"))
|
||||
panic(call.runtime.panicURIError("URI malformed"))
|
||||
}
|
||||
// input = ..., value, value1, ...
|
||||
value = value
|
||||
value1 := input[index]
|
||||
if value1 < 0xDC00 || value1 > 0xDFFF {
|
||||
panic(newURIError("URI malformed"))
|
||||
panic(call.runtime.panicURIError("URI malformed"))
|
||||
}
|
||||
decode = []rune{((rune(value) - 0xD800) * 0x400) + (rune(value1) - 0xDC00) + 0x10000}
|
||||
}
|
||||
|
|
@ -257,17 +256,17 @@ func _decodeURI(input string, reserve bool) (string, bool) {
|
|||
}
|
||||
|
||||
func builtinGlobal_decodeURI(call FunctionCall) Value {
|
||||
output, err := _decodeURI(toString(call.Argument(0)), true)
|
||||
output, err := _decodeURI(call.Argument(0).string(), true)
|
||||
if err {
|
||||
panic(newURIError("URI malformed"))
|
||||
panic(call.runtime.panicURIError("URI malformed"))
|
||||
}
|
||||
return toValue_string(output)
|
||||
}
|
||||
|
||||
func builtinGlobal_decodeURIComponent(call FunctionCall) Value {
|
||||
output, err := _decodeURI(toString(call.Argument(0)), false)
|
||||
output, err := _decodeURI(call.Argument(0).string(), false)
|
||||
if err {
|
||||
panic(newURIError("URI malformed"))
|
||||
panic(call.runtime.panicURIError("URI malformed"))
|
||||
}
|
||||
return toValue_string(output)
|
||||
}
|
||||
|
|
@ -346,48 +345,9 @@ func builtin_unescape(input string) string {
|
|||
}
|
||||
|
||||
func builtinGlobal_escape(call FunctionCall) Value {
|
||||
return toValue_string(builtin_escape(toString(call.Argument(0))))
|
||||
return toValue_string(builtin_escape(call.Argument(0).string()))
|
||||
}
|
||||
|
||||
func builtinGlobal_unescape(call FunctionCall) Value {
|
||||
return toValue_string(builtin_unescape(toString(call.Argument(0))))
|
||||
}
|
||||
|
||||
// Error
|
||||
|
||||
func builtinError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newError("", call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewError(self *_object, _ Value, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newError("", valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func builtinError_toString(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
if thisObject == nil {
|
||||
panic(newTypeError())
|
||||
}
|
||||
|
||||
name := "Error"
|
||||
nameValue := thisObject.get("name")
|
||||
if nameValue.IsDefined() {
|
||||
name = toString(nameValue)
|
||||
}
|
||||
|
||||
message := ""
|
||||
messageValue := thisObject.get("message")
|
||||
if messageValue.IsDefined() {
|
||||
message = toString(messageValue)
|
||||
}
|
||||
|
||||
if len(name) == 0 {
|
||||
return toValue_string(message)
|
||||
}
|
||||
|
||||
if len(message) == 0 {
|
||||
return toValue_string(name)
|
||||
}
|
||||
|
||||
return toValue_string(fmt.Sprintf("%s: %s", name, message))
|
||||
return toValue_string(builtin_unescape(call.Argument(0).string()))
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ func builtinArray(call FunctionCall) Value {
|
|||
return toValue_object(builtinNewArrayNative(call.runtime, call.ArgumentList))
|
||||
}
|
||||
|
||||
func builtinNewArray(self *_object, _ Value, argumentList []Value) Value {
|
||||
func builtinNewArray(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(builtinNewArrayNative(self.runtime, argumentList))
|
||||
}
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ func builtinNewArrayNative(runtime *_runtime, argumentList []Value) *_object {
|
|||
if len(argumentList) == 1 {
|
||||
firstArgument := argumentList[0]
|
||||
if firstArgument.IsNumber() {
|
||||
return runtime.newArray(arrayUint32(firstArgument))
|
||||
return runtime.newArray(arrayUint32(runtime, firstArgument))
|
||||
}
|
||||
}
|
||||
return runtime.newArrayOf(argumentList)
|
||||
|
|
@ -30,7 +30,7 @@ func builtinArray_toString(call FunctionCall) Value {
|
|||
join := thisObject.get("join")
|
||||
if join.isCallable() {
|
||||
join := join._object()
|
||||
return join.Call(call.This, call.ArgumentList)
|
||||
return join.call(call.This, call.ArgumentList, false, nativeFrame)
|
||||
}
|
||||
return builtinObject_toString(call)
|
||||
}
|
||||
|
|
@ -46,15 +46,15 @@ func builtinArray_toLocaleString(call FunctionCall) Value {
|
|||
for index := int64(0); index < length; index += 1 {
|
||||
value := thisObject.get(arrayIndexToString(index))
|
||||
stringValue := ""
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueEmpty, valueUndefined, valueNull:
|
||||
default:
|
||||
object := call.runtime.toObject(value)
|
||||
toLocaleString := object.get("toLocaleString")
|
||||
if !toLocaleString.isCallable() {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
stringValue = toLocaleString.call(toValue_object(object)).toString()
|
||||
stringValue = toLocaleString.call(call.runtime, toValue_object(object)).string()
|
||||
}
|
||||
stringList = append(stringList, stringValue)
|
||||
}
|
||||
|
|
@ -66,11 +66,11 @@ func builtinArray_concat(call FunctionCall) Value {
|
|||
valueArray := []Value{}
|
||||
source := append([]Value{toValue_object(thisObject)}, call.ArgumentList...)
|
||||
for _, item := range source {
|
||||
switch item._valueType {
|
||||
switch item.kind {
|
||||
case valueObject:
|
||||
object := item._object()
|
||||
if isArray(object) {
|
||||
length := toInteger(object.get("length")).value
|
||||
length := object.get("length").number().int64
|
||||
for index := int64(0); index < length; index += 1 {
|
||||
name := strconv.FormatInt(index, 10)
|
||||
if object.hasProperty(name) {
|
||||
|
|
@ -94,7 +94,7 @@ func builtinArray_shift(call FunctionCall) Value {
|
|||
length := int64(toUint32(thisObject.get("length")))
|
||||
if 0 == length {
|
||||
thisObject.put("length", toValue_int64(0), true)
|
||||
return UndefinedValue()
|
||||
return Value{}
|
||||
}
|
||||
first := thisObject.get("0")
|
||||
for index := int64(1); index < length; index++ {
|
||||
|
|
@ -130,7 +130,7 @@ func builtinArray_pop(call FunctionCall) Value {
|
|||
length := int64(toUint32(thisObject.get("length")))
|
||||
if 0 == length {
|
||||
thisObject.put("length", toValue_uint32(0), true)
|
||||
return UndefinedValue()
|
||||
return Value{}
|
||||
}
|
||||
last := thisObject.get(arrayIndexToString(length - 1))
|
||||
thisObject.delete(arrayIndexToString(length-1), true)
|
||||
|
|
@ -143,7 +143,7 @@ func builtinArray_join(call FunctionCall) Value {
|
|||
{
|
||||
argument := call.Argument(0)
|
||||
if argument.IsDefined() {
|
||||
separator = toString(argument)
|
||||
separator = argument.string()
|
||||
}
|
||||
}
|
||||
thisObject := call.thisObject()
|
||||
|
|
@ -155,10 +155,10 @@ func builtinArray_join(call FunctionCall) Value {
|
|||
for index := int64(0); index < length; index += 1 {
|
||||
value := thisObject.get(arrayIndexToString(index))
|
||||
stringValue := ""
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueEmpty, valueUndefined, valueNull:
|
||||
default:
|
||||
stringValue = toString(value)
|
||||
stringValue = value.string()
|
||||
}
|
||||
stringList = append(stringList, stringValue)
|
||||
}
|
||||
|
|
@ -370,8 +370,8 @@ func sortCompare(thisObject *_object, index0, index1 uint, compare *_object) int
|
|||
}
|
||||
|
||||
if compare == nil {
|
||||
j.value = toString(x)
|
||||
k.value = toString(y)
|
||||
j.value = x.string()
|
||||
k.value = y.string()
|
||||
|
||||
if j.value == k.value {
|
||||
return 0
|
||||
|
|
@ -382,7 +382,7 @@ func sortCompare(thisObject *_object, index0, index1 uint, compare *_object) int
|
|||
return 1
|
||||
}
|
||||
|
||||
return int(toInt32(compare.Call(UndefinedValue(), []Value{x, y})))
|
||||
return int(toInt32(compare.call(Value{}, []Value{x, y}, false, nativeFrame)))
|
||||
}
|
||||
|
||||
func arraySortSwap(thisObject *_object, index0, index1 uint) {
|
||||
|
|
@ -447,7 +447,7 @@ func builtinArray_sort(call FunctionCall) Value {
|
|||
compare := compareValue._object()
|
||||
if compareValue.IsUndefined() {
|
||||
} else if !compareValue.isCallable() {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
if length > 1 {
|
||||
arraySortQuickSort(thisObject, 0, length-1, compare)
|
||||
|
|
@ -464,7 +464,7 @@ func builtinArray_indexOf(call FunctionCall) Value {
|
|||
if length := int64(toUint32(thisObject.get("length"))); length > 0 {
|
||||
index := int64(0)
|
||||
if len(call.ArgumentList) > 1 {
|
||||
index = toInteger(call.Argument(1)).value
|
||||
index = call.Argument(1).number().int64
|
||||
}
|
||||
if index < 0 {
|
||||
if index += length; index < 0 {
|
||||
|
|
@ -492,7 +492,7 @@ func builtinArray_lastIndexOf(call FunctionCall) Value {
|
|||
length := int64(toUint32(thisObject.get("length")))
|
||||
index := length - 1
|
||||
if len(call.ArgumentList) > 1 {
|
||||
index = toInteger(call.Argument(1)).value
|
||||
index = call.Argument(1).number().int64
|
||||
}
|
||||
if 0 > index {
|
||||
index += length
|
||||
|
|
@ -523,15 +523,15 @@ func builtinArray_every(call FunctionCall) Value {
|
|||
callThis := call.Argument(1)
|
||||
for index := int64(0); index < length; index++ {
|
||||
if key := arrayIndexToString(index); thisObject.hasProperty(key) {
|
||||
if value := thisObject.get(key); iterator.call(callThis, value, toValue_int64(index), this).isTrue() {
|
||||
if value := thisObject.get(key); iterator.call(call.runtime, callThis, value, toValue_int64(index), this).bool() {
|
||||
continue
|
||||
}
|
||||
return FalseValue()
|
||||
return falseValue
|
||||
}
|
||||
}
|
||||
return TrueValue()
|
||||
return trueValue
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
func builtinArray_some(call FunctionCall) Value {
|
||||
|
|
@ -542,14 +542,14 @@ func builtinArray_some(call FunctionCall) Value {
|
|||
callThis := call.Argument(1)
|
||||
for index := int64(0); index < length; index++ {
|
||||
if key := arrayIndexToString(index); thisObject.hasProperty(key) {
|
||||
if value := thisObject.get(key); iterator.call(callThis, value, toValue_int64(index), this).isTrue() {
|
||||
return TrueValue()
|
||||
if value := thisObject.get(key); iterator.call(call.runtime, callThis, value, toValue_int64(index), this).bool() {
|
||||
return trueValue
|
||||
}
|
||||
}
|
||||
}
|
||||
return FalseValue()
|
||||
return falseValue
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
func builtinArray_forEach(call FunctionCall) Value {
|
||||
|
|
@ -560,12 +560,12 @@ func builtinArray_forEach(call FunctionCall) Value {
|
|||
callThis := call.Argument(1)
|
||||
for index := int64(0); index < length; index++ {
|
||||
if key := arrayIndexToString(index); thisObject.hasProperty(key) {
|
||||
iterator.call(callThis, thisObject.get(key), toValue_int64(index), this)
|
||||
iterator.call(call.runtime, callThis, thisObject.get(key), toValue_int64(index), this)
|
||||
}
|
||||
}
|
||||
return UndefinedValue()
|
||||
return Value{}
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
func builtinArray_map(call FunctionCall) Value {
|
||||
|
|
@ -577,14 +577,14 @@ func builtinArray_map(call FunctionCall) Value {
|
|||
values := make([]Value, length)
|
||||
for index := int64(0); index < length; index++ {
|
||||
if key := arrayIndexToString(index); thisObject.hasProperty(key) {
|
||||
values[index] = iterator.call(callThis, thisObject.get(key), index, this)
|
||||
values[index] = iterator.call(call.runtime, callThis, thisObject.get(key), index, this)
|
||||
} else {
|
||||
values[index] = UndefinedValue()
|
||||
values[index] = Value{}
|
||||
}
|
||||
}
|
||||
return toValue_object(call.runtime.newArrayOf(values))
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
func builtinArray_filter(call FunctionCall) Value {
|
||||
|
|
@ -597,14 +597,14 @@ func builtinArray_filter(call FunctionCall) Value {
|
|||
for index := int64(0); index < length; index++ {
|
||||
if key := arrayIndexToString(index); thisObject.hasProperty(key) {
|
||||
value := thisObject.get(key)
|
||||
if iterator.call(callThis, value, index, this).isTrue() {
|
||||
if iterator.call(call.runtime, callThis, value, index, this).bool() {
|
||||
values = append(values, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return toValue_object(call.runtime.newArrayOf(values))
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
func builtinArray_reduce(call FunctionCall) Value {
|
||||
|
|
@ -630,13 +630,13 @@ func builtinArray_reduce(call FunctionCall) Value {
|
|||
}
|
||||
for ; index < length; index++ {
|
||||
if key := arrayIndexToString(index); thisObject.hasProperty(key) {
|
||||
accumulator = iterator.call(UndefinedValue(), accumulator, thisObject.get(key), key, this)
|
||||
accumulator = iterator.call(call.runtime, Value{}, accumulator, thisObject.get(key), key, this)
|
||||
}
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
func builtinArray_reduceRight(call FunctionCall) Value {
|
||||
|
|
@ -662,11 +662,11 @@ func builtinArray_reduceRight(call FunctionCall) Value {
|
|||
}
|
||||
for ; index >= 0; index-- {
|
||||
if key := arrayIndexToString(index); thisObject.hasProperty(key) {
|
||||
accumulator = iterator.call(UndefinedValue(), accumulator, thisObject.get(key), key, this)
|
||||
accumulator = iterator.call(call.runtime, Value{}, accumulator, thisObject.get(key), key, this)
|
||||
}
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
|
@ -3,10 +3,10 @@ package otto
|
|||
// Boolean
|
||||
|
||||
func builtinBoolean(call FunctionCall) Value {
|
||||
return toValue_bool(toBoolean(call.Argument(0)))
|
||||
return toValue_bool(call.Argument(0).bool())
|
||||
}
|
||||
|
||||
func builtinNewBoolean(self *_object, _ Value, argumentList []Value) Value {
|
||||
func builtinNewBoolean(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newBoolean(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ func builtinBoolean_toString(call FunctionCall) Value {
|
|||
// Will throw a TypeError if ThisObject is not a Boolean
|
||||
value = call.thisClassObject("Boolean").primitiveValue()
|
||||
}
|
||||
return toValue_string(toString(value))
|
||||
return toValue_string(value.string())
|
||||
}
|
||||
|
||||
func builtinBoolean_valueOf(call FunctionCall) Value {
|
||||
|
|
@ -21,12 +21,12 @@ func builtinDate(call FunctionCall) Value {
|
|||
return toValue_string(date.Time().Format(builtinDate_goDateTimeLayout))
|
||||
}
|
||||
|
||||
func builtinNewDate(self *_object, _ Value, argumentList []Value) Value {
|
||||
func builtinNewDate(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newDate(newDateTime(argumentList, Time.Local)))
|
||||
}
|
||||
|
||||
func builtinDate_toString(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return toValue_string("Invalid Date")
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ func builtinDate_toString(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_toDateString(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return toValue_string("Invalid Date")
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ func builtinDate_toDateString(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_toTimeString(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return toValue_string("Invalid Date")
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ func builtinDate_toTimeString(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_toUTCString(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return toValue_string("Invalid Date")
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ func builtinDate_toUTCString(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_toISOString(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return toValue_string("Invalid Date")
|
||||
}
|
||||
|
|
@ -69,20 +69,21 @@ func builtinDate_toJSON(call FunctionCall) Value {
|
|||
object := call.thisObject()
|
||||
value := object.DefaultValue(defaultValueHintNumber) // FIXME object.primitiveNumberValue
|
||||
{ // FIXME value.isFinite
|
||||
value := toFloat(value)
|
||||
value := value.float64()
|
||||
if math.IsNaN(value) || math.IsInf(value, 0) {
|
||||
return NullValue()
|
||||
return nullValue
|
||||
}
|
||||
}
|
||||
toISOString := object.get("toISOString")
|
||||
if !toISOString.isCallable() {
|
||||
panic(newTypeError())
|
||||
// FIXME
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
return toISOString.call(toValue_object(object), []Value{})
|
||||
return toISOString.call(call.runtime, toValue_object(object), []Value{})
|
||||
}
|
||||
|
||||
func builtinDate_toGMTString(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return toValue_string("Invalid Date")
|
||||
}
|
||||
|
|
@ -90,7 +91,7 @@ func builtinDate_toGMTString(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getTime(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -101,15 +102,15 @@ func builtinDate_getTime(call FunctionCall) Value {
|
|||
|
||||
func builtinDate_setTime(call FunctionCall) Value {
|
||||
object := call.thisObject()
|
||||
date := dateObjectOf(object)
|
||||
date.Set(toFloat(call.Argument(0)))
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
date.Set(call.Argument(0).float64())
|
||||
object.value = date
|
||||
return date.Value()
|
||||
}
|
||||
|
||||
func _builtinDate_beforeSet(call FunctionCall, argumentLimit int, timeLocal bool) (*_object, *_dateObject, *_ecmaTime, []int) {
|
||||
object := call.thisObject()
|
||||
date := dateObjectOf(object)
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
|
|
@ -126,16 +127,14 @@ func _builtinDate_beforeSet(call FunctionCall, argumentLimit int, timeLocal bool
|
|||
valueList := make([]int, argumentLimit)
|
||||
for index := 0; index < argumentLimit; index++ {
|
||||
value := call.ArgumentList[index]
|
||||
if value.IsNaN() {
|
||||
nm := value.number()
|
||||
switch nm.kind {
|
||||
case numberInteger, numberFloat:
|
||||
default:
|
||||
object.value = invalidDateObject
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
integer := toInteger(value)
|
||||
if !integer.valid() {
|
||||
object.value = invalidDateObject
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
valueList[index] = int(integer.value)
|
||||
valueList[index] = int(nm.int64)
|
||||
}
|
||||
baseTime := date.Time()
|
||||
if timeLocal {
|
||||
|
|
@ -146,7 +145,7 @@ func _builtinDate_beforeSet(call FunctionCall, argumentLimit int, timeLocal bool
|
|||
}
|
||||
|
||||
func builtinDate_parse(call FunctionCall) Value {
|
||||
date := toString(call.Argument(0))
|
||||
date := call.Argument(0).string()
|
||||
return toValue_float64(dateParse(date))
|
||||
}
|
||||
|
||||
|
|
@ -161,7 +160,7 @@ func builtinDate_now(call FunctionCall) Value {
|
|||
|
||||
// This is a placeholder
|
||||
func builtinDate_toLocaleString(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return toValue_string("Invalid Date")
|
||||
}
|
||||
|
|
@ -170,7 +169,7 @@ func builtinDate_toLocaleString(call FunctionCall) Value {
|
|||
|
||||
// This is a placeholder
|
||||
func builtinDate_toLocaleDateString(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return toValue_string("Invalid Date")
|
||||
}
|
||||
|
|
@ -179,7 +178,7 @@ func builtinDate_toLocaleDateString(call FunctionCall) Value {
|
|||
|
||||
// This is a placeholder
|
||||
func builtinDate_toLocaleTimeString(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return toValue_string("Invalid Date")
|
||||
}
|
||||
|
|
@ -187,7 +186,7 @@ func builtinDate_toLocaleTimeString(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_valueOf(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -197,7 +196,7 @@ func builtinDate_valueOf(call FunctionCall) Value {
|
|||
func builtinDate_getYear(call FunctionCall) Value {
|
||||
// Will throw a TypeError is ThisObject is nil or
|
||||
// does not have Class of "Date"
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -207,7 +206,7 @@ func builtinDate_getYear(call FunctionCall) Value {
|
|||
func builtinDate_getFullYear(call FunctionCall) Value {
|
||||
// Will throw a TypeError is ThisObject is nil or
|
||||
// does not have Class of "Date"
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -215,7 +214,7 @@ func builtinDate_getFullYear(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getUTCFullYear(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -223,7 +222,7 @@ func builtinDate_getUTCFullYear(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getMonth(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -231,7 +230,7 @@ func builtinDate_getMonth(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getUTCMonth(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -239,7 +238,7 @@ func builtinDate_getUTCMonth(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getDate(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -247,7 +246,7 @@ func builtinDate_getDate(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getUTCDate(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -256,7 +255,7 @@ func builtinDate_getUTCDate(call FunctionCall) Value {
|
|||
|
||||
func builtinDate_getDay(call FunctionCall) Value {
|
||||
// Actually day of the week
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -264,7 +263,7 @@ func builtinDate_getDay(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getUTCDay(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -272,7 +271,7 @@ func builtinDate_getUTCDay(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getHours(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -280,7 +279,7 @@ func builtinDate_getHours(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getUTCHours(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -288,7 +287,7 @@ func builtinDate_getUTCHours(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getMinutes(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -296,7 +295,7 @@ func builtinDate_getMinutes(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getUTCMinutes(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -304,7 +303,7 @@ func builtinDate_getUTCMinutes(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getSeconds(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -312,7 +311,7 @@ func builtinDate_getSeconds(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getUTCSeconds(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -320,7 +319,7 @@ func builtinDate_getUTCSeconds(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getMilliseconds(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -328,7 +327,7 @@ func builtinDate_getMilliseconds(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getUTCMilliseconds(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -336,7 +335,7 @@ func builtinDate_getUTCMilliseconds(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinDate_getTimezoneOffset(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
date := dateObjectOf(call.runtime, call.thisObject())
|
||||
if date.isNaN {
|
||||
return NaNValue()
|
||||
}
|
||||
126
Godeps/_workspace/src/github.com/robertkrimen/otto/builtin_error.go
generated
vendored
Normal file
126
Godeps/_workspace/src/github.com/robertkrimen/otto/builtin_error.go
generated
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func builtinError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newError("", call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewError(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newError("", valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func builtinError_toString(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
if thisObject == nil {
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
name := "Error"
|
||||
nameValue := thisObject.get("name")
|
||||
if nameValue.IsDefined() {
|
||||
name = nameValue.string()
|
||||
}
|
||||
|
||||
message := ""
|
||||
messageValue := thisObject.get("message")
|
||||
if messageValue.IsDefined() {
|
||||
message = messageValue.string()
|
||||
}
|
||||
|
||||
if len(name) == 0 {
|
||||
return toValue_string(message)
|
||||
}
|
||||
|
||||
if len(message) == 0 {
|
||||
return toValue_string(name)
|
||||
}
|
||||
|
||||
return toValue_string(fmt.Sprintf("%s: %s", name, message))
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newEvalError(message Value) *_object {
|
||||
self := runtime.newErrorObject("EvalError", message)
|
||||
self.prototype = runtime.global.EvalErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func builtinEvalError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newEvalError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewEvalError(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newEvalError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newTypeError(message Value) *_object {
|
||||
self := runtime.newErrorObject("TypeError", message)
|
||||
self.prototype = runtime.global.TypeErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func builtinTypeError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newTypeError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewTypeError(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newTypeError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newRangeError(message Value) *_object {
|
||||
self := runtime.newErrorObject("RangeError", message)
|
||||
self.prototype = runtime.global.RangeErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func builtinRangeError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newRangeError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewRangeError(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newRangeError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newURIError(message Value) *_object {
|
||||
self := runtime.newErrorObject("URIError", message)
|
||||
self.prototype = runtime.global.URIErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newReferenceError(message Value) *_object {
|
||||
self := runtime.newErrorObject("ReferenceError", message)
|
||||
self.prototype = runtime.global.ReferenceErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func builtinReferenceError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newReferenceError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewReferenceError(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newReferenceError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func (runtime *_runtime) newSyntaxError(message Value) *_object {
|
||||
self := runtime.newErrorObject("SyntaxError", message)
|
||||
self.prototype = runtime.global.SyntaxErrorPrototype
|
||||
return self
|
||||
}
|
||||
|
||||
func builtinSyntaxError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newSyntaxError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewSyntaxError(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newSyntaxError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
||||
func builtinURIError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newURIError(call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinNewURIError(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newURIError(valueOfArrayIndex(argumentList, 0)))
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
|
@ -14,14 +15,14 @@ func builtinFunction(call FunctionCall) Value {
|
|||
return toValue_object(builtinNewFunctionNative(call.runtime, call.ArgumentList))
|
||||
}
|
||||
|
||||
func builtinNewFunction(self *_object, _ Value, argumentList []Value) Value {
|
||||
func builtinNewFunction(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(builtinNewFunctionNative(self.runtime, argumentList))
|
||||
}
|
||||
|
||||
func argumentList2parameterList(argumentList []Value) []string {
|
||||
parameterList := make([]string, 0, len(argumentList))
|
||||
for _, value := range argumentList {
|
||||
tmp := strings.FieldsFunc(toString(value), func(chr rune) bool {
|
||||
tmp := strings.FieldsFunc(value.string(), func(chr rune) bool {
|
||||
return chr == ',' || unicode.IsSpace(chr)
|
||||
})
|
||||
parameterList = append(parameterList, tmp...)
|
||||
|
|
@ -37,40 +38,51 @@ func builtinNewFunctionNative(runtime *_runtime, argumentList []Value) *_object
|
|||
if count > 0 {
|
||||
tmp := make([]string, 0, count-1)
|
||||
for _, value := range argumentList[0 : count-1] {
|
||||
tmp = append(tmp, toString(value))
|
||||
tmp = append(tmp, value.string())
|
||||
}
|
||||
parameterList = strings.Join(tmp, ",")
|
||||
body = toString(argumentList[count-1])
|
||||
body = argumentList[count-1].string()
|
||||
}
|
||||
|
||||
// FIXME
|
||||
function, err := parser.ParseFunction(parameterList, body)
|
||||
runtime.parseThrow(err) // Will panic/throw appropriately
|
||||
cmpl_function := parseExpression(function)
|
||||
cmpl := _compiler{}
|
||||
cmpl_function := cmpl.parseExpression(function)
|
||||
|
||||
return runtime.newNodeFunction(cmpl_function.(*_nodeFunctionLiteral), runtime.GlobalEnvironment)
|
||||
return runtime.newNodeFunction(cmpl_function.(*_nodeFunctionLiteral), runtime.globalStash)
|
||||
}
|
||||
|
||||
func builtinFunction_toString(call FunctionCall) Value {
|
||||
object := call.thisClassObject("Function") // Should throw a TypeError unless Function
|
||||
return toValue_string(object.value.(_functionObject).source(object))
|
||||
switch fn := object.value.(type) {
|
||||
case _nativeFunctionObject:
|
||||
return toValue_string(fmt.Sprintf("function %s() { [native code] }", fn.name))
|
||||
case _nodeFunctionObject:
|
||||
return toValue_string(fn.node.source)
|
||||
case _bindFunctionObject:
|
||||
return toValue_string("function () { [native code] }")
|
||||
}
|
||||
|
||||
panic(call.runtime.panicTypeError("Function.toString()"))
|
||||
}
|
||||
|
||||
func builtinFunction_apply(call FunctionCall) Value {
|
||||
if !call.This.isCallable() {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
this := call.Argument(0)
|
||||
if this.IsUndefined() {
|
||||
// FIXME Not ECMA5
|
||||
this = toValue_object(call.runtime.GlobalObject)
|
||||
this = toValue_object(call.runtime.globalObject)
|
||||
}
|
||||
argumentList := call.Argument(1)
|
||||
switch argumentList._valueType {
|
||||
switch argumentList.kind {
|
||||
case valueUndefined, valueNull:
|
||||
return call.thisObject().Call(this, []Value{})
|
||||
return call.thisObject().call(this, nil, false, nativeFrame)
|
||||
case valueObject:
|
||||
default:
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
arrayObject := argumentList._object()
|
||||
|
|
@ -80,29 +92,29 @@ func builtinFunction_apply(call FunctionCall) Value {
|
|||
for index := int64(0); index < length; index++ {
|
||||
valueArray[index] = arrayObject.get(arrayIndexToString(index))
|
||||
}
|
||||
return thisObject.Call(this, valueArray)
|
||||
return thisObject.call(this, valueArray, false, nativeFrame)
|
||||
}
|
||||
|
||||
func builtinFunction_call(call FunctionCall) Value {
|
||||
if !call.This.isCallable() {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
thisObject := call.thisObject()
|
||||
this := call.Argument(0)
|
||||
if this.IsUndefined() {
|
||||
// FIXME Not ECMA5
|
||||
this = toValue_object(call.runtime.GlobalObject)
|
||||
this = toValue_object(call.runtime.globalObject)
|
||||
}
|
||||
if len(call.ArgumentList) >= 1 {
|
||||
return thisObject.Call(this, call.ArgumentList[1:])
|
||||
return thisObject.call(this, call.ArgumentList[1:], false, nativeFrame)
|
||||
}
|
||||
return thisObject.Call(this, []Value{})
|
||||
return thisObject.call(this, nil, false, nativeFrame)
|
||||
}
|
||||
|
||||
func builtinFunction_bind(call FunctionCall) Value {
|
||||
target := call.This
|
||||
if !target.isCallable() {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
targetObject := target._object()
|
||||
|
||||
|
|
@ -110,7 +122,7 @@ func builtinFunction_bind(call FunctionCall) Value {
|
|||
argumentList := call.slice(1)
|
||||
if this.IsUndefined() {
|
||||
// FIXME Do this elsewhere?
|
||||
this = toValue_object(call.runtime.GlobalObject)
|
||||
this = toValue_object(call.runtime.globalObject)
|
||||
}
|
||||
|
||||
return toValue_object(call.runtime.newBoundFunction(targetObject, this, argumentList))
|
||||
|
|
@ -3,7 +3,7 @@ package otto
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
|
@ -23,13 +23,13 @@ func builtinJSON_parse(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
var root interface{}
|
||||
err := json.Unmarshal([]byte(toString(call.Argument(0))), &root)
|
||||
err := json.Unmarshal([]byte(call.Argument(0).string()), &root)
|
||||
if err != nil {
|
||||
panic(newSyntaxError(err.Error()))
|
||||
panic(call.runtime.panicSyntaxError(err.Error()))
|
||||
}
|
||||
value, exists := builtinJSON_parseWalk(ctx, root)
|
||||
if !exists {
|
||||
value = UndefinedValue()
|
||||
value = Value{}
|
||||
}
|
||||
if revive {
|
||||
root := ctx.call.runtime.newObject()
|
||||
|
|
@ -65,13 +65,13 @@ func builtinJSON_reviveWalk(ctx _builtinJSON_parseContext, holder *_object, name
|
|||
})
|
||||
}
|
||||
}
|
||||
return ctx.reviver.call(toValue_object(holder), name, value)
|
||||
return ctx.reviver.call(ctx.call.runtime, toValue_object(holder), name, value)
|
||||
}
|
||||
|
||||
func builtinJSON_parseWalk(ctx _builtinJSON_parseContext, rawValue interface{}) (Value, bool) {
|
||||
switch value := rawValue.(type) {
|
||||
case nil:
|
||||
return NullValue(), true
|
||||
return nullValue, true
|
||||
case bool:
|
||||
return toValue_bool(value), true
|
||||
case string:
|
||||
|
|
@ -120,7 +120,7 @@ func builtinJSON_stringify(call FunctionCall) Value {
|
|||
length = 0
|
||||
for index, _ := range propertyList {
|
||||
value := replacer.get(arrayIndexToString(int64(index)))
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueObject:
|
||||
switch value.value.(*_object).class {
|
||||
case "String":
|
||||
|
|
@ -133,7 +133,7 @@ func builtinJSON_stringify(call FunctionCall) Value {
|
|||
default:
|
||||
continue
|
||||
}
|
||||
name := toString(value)
|
||||
name := value.string()
|
||||
if seen[name] {
|
||||
continue
|
||||
}
|
||||
|
|
@ -148,24 +148,24 @@ func builtinJSON_stringify(call FunctionCall) Value {
|
|||
}
|
||||
}
|
||||
if spaceValue, exists := call.getArgument(2); exists {
|
||||
if spaceValue._valueType == valueObject {
|
||||
if spaceValue.kind == valueObject {
|
||||
switch spaceValue.value.(*_object).class {
|
||||
case "String":
|
||||
spaceValue = toValue_string(toString(spaceValue))
|
||||
spaceValue = toValue_string(spaceValue.string())
|
||||
case "Number":
|
||||
spaceValue = toNumber(spaceValue)
|
||||
spaceValue = spaceValue.numberValue()
|
||||
}
|
||||
}
|
||||
switch spaceValue._valueType {
|
||||
switch spaceValue.kind {
|
||||
case valueString:
|
||||
value := toString(spaceValue)
|
||||
value := spaceValue.string()
|
||||
if len(value) > 10 {
|
||||
ctx.gap = value[0:10]
|
||||
} else {
|
||||
ctx.gap = value
|
||||
}
|
||||
case valueNumber:
|
||||
value := toInteger(spaceValue).value
|
||||
value := spaceValue.number().int64
|
||||
if value > 10 {
|
||||
value = 10
|
||||
} else if value < 0 {
|
||||
|
|
@ -178,11 +178,11 @@ func builtinJSON_stringify(call FunctionCall) Value {
|
|||
holder.put("", call.Argument(0), false)
|
||||
value, exists := builtinJSON_stringifyWalk(ctx, "", holder)
|
||||
if !exists {
|
||||
return UndefinedValue()
|
||||
return Value{}
|
||||
}
|
||||
valueJSON, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
panic(newTypeError(err.Error()))
|
||||
panic(call.runtime.panicTypeError(err.Error()))
|
||||
}
|
||||
if ctx.gap != "" {
|
||||
valueJSON1 := bytes.Buffer{}
|
||||
|
|
@ -198,7 +198,7 @@ func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, ho
|
|||
if value.IsObject() {
|
||||
object := value._object()
|
||||
if toJSON := object.get("toJSON"); toJSON.IsFunction() {
|
||||
value = toJSON.call(value, key)
|
||||
value = toJSON.call(ctx.call.runtime, value, key)
|
||||
} else {
|
||||
// If the object is a GoStruct or something that implements json.Marshaler
|
||||
if object.objectClass.marshalJSON != nil {
|
||||
|
|
@ -211,31 +211,35 @@ func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, ho
|
|||
}
|
||||
|
||||
if ctx.replacerFunction != nil {
|
||||
value = (*ctx.replacerFunction).call(toValue_object(holder), key, value)
|
||||
value = (*ctx.replacerFunction).call(ctx.call.runtime, toValue_object(holder), key, value)
|
||||
}
|
||||
|
||||
if value._valueType == valueObject {
|
||||
if value.kind == valueObject {
|
||||
switch value.value.(*_object).class {
|
||||
case "Boolean":
|
||||
value = value._object().value.(Value)
|
||||
case "String":
|
||||
value = toValue_string(toString(value))
|
||||
value = toValue_string(value.string())
|
||||
case "Number":
|
||||
value = toNumber(value)
|
||||
value = value.numberValue()
|
||||
}
|
||||
}
|
||||
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueBoolean:
|
||||
return toBoolean(value), true
|
||||
return value.bool(), true
|
||||
case valueString:
|
||||
return toString(value), true
|
||||
return value.string(), true
|
||||
case valueNumber:
|
||||
value := toFloat(value)
|
||||
if math.IsNaN(value) || math.IsInf(value, 0) {
|
||||
integer := value.number()
|
||||
switch integer.kind {
|
||||
case numberInteger:
|
||||
return integer.int64, true
|
||||
case numberFloat:
|
||||
return integer.float64, true
|
||||
default:
|
||||
return nil, true
|
||||
}
|
||||
return value, true
|
||||
case valueNull:
|
||||
return nil, true
|
||||
case valueObject:
|
||||
|
|
@ -243,14 +247,24 @@ func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, ho
|
|||
if value := value._object(); nil != value {
|
||||
for _, object := range ctx.stack {
|
||||
if holder == object {
|
||||
panic(newTypeError("Converting circular structure to JSON"))
|
||||
panic(ctx.call.runtime.panicTypeError("Converting circular structure to JSON"))
|
||||
}
|
||||
}
|
||||
ctx.stack = append(ctx.stack, value)
|
||||
defer func() { ctx.stack = ctx.stack[:len(ctx.stack)-1] }()
|
||||
}
|
||||
if isArray(holder) {
|
||||
length := holder.get("length").value.(uint32)
|
||||
var length uint32
|
||||
switch value := holder.get("length").value.(type) {
|
||||
case uint32:
|
||||
length = value
|
||||
case int:
|
||||
if value >= 0 {
|
||||
length = uint32(value)
|
||||
}
|
||||
default:
|
||||
panic(ctx.call.runtime.panicTypeError(fmt.Sprintf("JSON.stringify: invalid length: %v (%[1]T)", value)))
|
||||
}
|
||||
array := make([]interface{}, length)
|
||||
for index, _ := range array {
|
||||
name := arrayIndexToString(int64(index))
|
||||
|
|
@ -8,31 +8,31 @@ import (
|
|||
// Math
|
||||
|
||||
func builtinMath_abs(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Abs(number))
|
||||
}
|
||||
|
||||
func builtinMath_acos(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Acos(number))
|
||||
}
|
||||
|
||||
func builtinMath_asin(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Asin(number))
|
||||
}
|
||||
|
||||
func builtinMath_atan(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Atan(number))
|
||||
}
|
||||
|
||||
func builtinMath_atan2(call FunctionCall) Value {
|
||||
y := toFloat(call.Argument(0))
|
||||
y := call.Argument(0).float64()
|
||||
if math.IsNaN(y) {
|
||||
return NaNValue()
|
||||
}
|
||||
x := toFloat(call.Argument(1))
|
||||
x := call.Argument(1).float64()
|
||||
if math.IsNaN(x) {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -40,27 +40,27 @@ func builtinMath_atan2(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinMath_cos(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Cos(number))
|
||||
}
|
||||
|
||||
func builtinMath_ceil(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Ceil(number))
|
||||
}
|
||||
|
||||
func builtinMath_exp(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Exp(number))
|
||||
}
|
||||
|
||||
func builtinMath_floor(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Floor(number))
|
||||
}
|
||||
|
||||
func builtinMath_log(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Log(number))
|
||||
}
|
||||
|
||||
|
|
@ -69,14 +69,14 @@ func builtinMath_max(call FunctionCall) Value {
|
|||
case 0:
|
||||
return negativeInfinityValue()
|
||||
case 1:
|
||||
return toValue_float64(toFloat(call.ArgumentList[0]))
|
||||
return toValue_float64(call.ArgumentList[0].float64())
|
||||
}
|
||||
result := toFloat(call.ArgumentList[0])
|
||||
result := call.ArgumentList[0].float64()
|
||||
if math.IsNaN(result) {
|
||||
return NaNValue()
|
||||
}
|
||||
for _, value := range call.ArgumentList[1:] {
|
||||
value := toFloat(value)
|
||||
value := value.float64()
|
||||
if math.IsNaN(value) {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -90,14 +90,14 @@ func builtinMath_min(call FunctionCall) Value {
|
|||
case 0:
|
||||
return positiveInfinityValue()
|
||||
case 1:
|
||||
return toValue_float64(toFloat(call.ArgumentList[0]))
|
||||
return toValue_float64(call.ArgumentList[0].float64())
|
||||
}
|
||||
result := toFloat(call.ArgumentList[0])
|
||||
result := call.ArgumentList[0].float64()
|
||||
if math.IsNaN(result) {
|
||||
return NaNValue()
|
||||
}
|
||||
for _, value := range call.ArgumentList[1:] {
|
||||
value := toFloat(value)
|
||||
value := value.float64()
|
||||
if math.IsNaN(value) {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -108,8 +108,8 @@ func builtinMath_min(call FunctionCall) Value {
|
|||
|
||||
func builtinMath_pow(call FunctionCall) Value {
|
||||
// TODO Make sure this works according to the specification (15.8.2.13)
|
||||
x := toFloat(call.Argument(0))
|
||||
y := toFloat(call.Argument(1))
|
||||
x := call.Argument(0).float64()
|
||||
y := call.Argument(1).float64()
|
||||
if math.Abs(x) == 1 && math.IsInf(y, 0) {
|
||||
return NaNValue()
|
||||
}
|
||||
|
|
@ -121,7 +121,7 @@ func builtinMath_random(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinMath_round(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
value := math.Floor(number + 0.5)
|
||||
if value == 0 {
|
||||
value = math.Copysign(0, number)
|
||||
|
|
@ -130,16 +130,16 @@ func builtinMath_round(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinMath_sin(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Sin(number))
|
||||
}
|
||||
|
||||
func builtinMath_sqrt(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Sqrt(number))
|
||||
}
|
||||
|
||||
func builtinMath_tan(call FunctionCall) Value {
|
||||
number := toFloat(call.Argument(0))
|
||||
number := call.Argument(0).float64()
|
||||
return toValue_float64(math.Tan(number))
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
func numberValueFromNumberArgumentList(argumentList []Value) Value {
|
||||
if len(argumentList) > 0 {
|
||||
return toNumber(argumentList[0])
|
||||
return argumentList[0].numberValue()
|
||||
}
|
||||
return toValue_int(0)
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ func builtinNumber(call FunctionCall) Value {
|
|||
return numberValueFromNumberArgumentList(call.ArgumentList)
|
||||
}
|
||||
|
||||
func builtinNewNumber(self *_object, _ Value, argumentList []Value) Value {
|
||||
func builtinNewNumber(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newNumber(numberValueFromNumberArgumentList(argumentList)))
|
||||
}
|
||||
|
||||
|
|
@ -30,12 +30,12 @@ func builtinNumber_toString(call FunctionCall) Value {
|
|||
if radixArgument.IsDefined() {
|
||||
integer := toIntegerFloat(radixArgument)
|
||||
if integer < 2 || integer > 36 {
|
||||
panic(newRangeError("RangeError: toString() radix must be between 2 and 36"))
|
||||
panic(call.runtime.panicRangeError("RangeError: toString() radix must be between 2 and 36"))
|
||||
}
|
||||
radix = int(integer)
|
||||
}
|
||||
if radix == 10 {
|
||||
return toValue_string(toString(value))
|
||||
return toValue_string(value.string())
|
||||
}
|
||||
return toValue_string(numberToStringRadix(value, radix))
|
||||
}
|
||||
|
|
@ -47,16 +47,16 @@ func builtinNumber_valueOf(call FunctionCall) Value {
|
|||
func builtinNumber_toFixed(call FunctionCall) Value {
|
||||
precision := toIntegerFloat(call.Argument(0))
|
||||
if 20 < precision || 0 > precision {
|
||||
panic(newRangeError("toFixed() precision must be between 0 and 20"))
|
||||
panic(call.runtime.panicRangeError("toFixed() precision must be between 0 and 20"))
|
||||
}
|
||||
if call.This.IsNaN() {
|
||||
return toValue_string("NaN")
|
||||
}
|
||||
value := toFloat(call.This)
|
||||
value := call.This.float64()
|
||||
if math.Abs(value) >= 1e21 {
|
||||
return toValue_string(floatToString(value, 64))
|
||||
}
|
||||
return toValue_string(strconv.FormatFloat(toFloat(call.This), 'f', int(precision), 64))
|
||||
return toValue_string(strconv.FormatFloat(call.This.float64(), 'f', int(precision), 64))
|
||||
}
|
||||
|
||||
func builtinNumber_toExponential(call FunctionCall) Value {
|
||||
|
|
@ -67,10 +67,10 @@ func builtinNumber_toExponential(call FunctionCall) Value {
|
|||
if value := call.Argument(0); value.IsDefined() {
|
||||
precision = toIntegerFloat(value)
|
||||
if 0 > precision {
|
||||
panic(newRangeError("RangeError: toExponential() precision must be greater than 0"))
|
||||
panic(call.runtime.panicRangeError("RangeError: toString() radix must be between 2 and 36"))
|
||||
}
|
||||
}
|
||||
return toValue_string(strconv.FormatFloat(toFloat(call.This), 'e', int(precision), 64))
|
||||
return toValue_string(strconv.FormatFloat(call.This.float64(), 'e', int(precision), 64))
|
||||
}
|
||||
|
||||
func builtinNumber_toPrecision(call FunctionCall) Value {
|
||||
|
|
@ -79,13 +79,13 @@ func builtinNumber_toPrecision(call FunctionCall) Value {
|
|||
}
|
||||
value := call.Argument(0)
|
||||
if value.IsUndefined() {
|
||||
return toValue_string(toString(call.This))
|
||||
return toValue_string(call.This.string())
|
||||
}
|
||||
precision := toIntegerFloat(value)
|
||||
if 1 > precision {
|
||||
panic(newRangeError("RangeError: toPrecision() precision must be greater than 1"))
|
||||
panic(call.runtime.panicRangeError("RangeError: toPrecision() precision must be greater than 1"))
|
||||
}
|
||||
return toValue_string(strconv.FormatFloat(toFloat(call.This), 'g', int(precision), 64))
|
||||
return toValue_string(strconv.FormatFloat(call.This.float64(), 'g', int(precision), 64))
|
||||
}
|
||||
|
||||
func builtinNumber_toLocaleString(call FunctionCall) Value {
|
||||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
func builtinObject(call FunctionCall) Value {
|
||||
value := call.Argument(0)
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueUndefined, valueNull:
|
||||
return toValue_object(call.runtime.newObject())
|
||||
}
|
||||
|
|
@ -16,9 +16,9 @@ func builtinObject(call FunctionCall) Value {
|
|||
return toValue_object(call.runtime.toObject(value))
|
||||
}
|
||||
|
||||
func builtinNewObject(self *_object, _ Value, argumentList []Value) Value {
|
||||
func builtinNewObject(self *_object, argumentList []Value) Value {
|
||||
value := valueOfArrayIndex(argumentList, 0)
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueNull, valueUndefined:
|
||||
case valueNumber, valueString, valueBoolean:
|
||||
return toValue_object(self.runtime.toObject(value))
|
||||
|
|
@ -34,7 +34,7 @@ func builtinObject_valueOf(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinObject_hasOwnProperty(call FunctionCall) Value {
|
||||
propertyName := toString(call.Argument(0))
|
||||
propertyName := call.Argument(0).string()
|
||||
thisObject := call.thisObject()
|
||||
return toValue_bool(thisObject.hasOwnProperty(propertyName))
|
||||
}
|
||||
|
|
@ -42,27 +42,27 @@ func builtinObject_hasOwnProperty(call FunctionCall) Value {
|
|||
func builtinObject_isPrototypeOf(call FunctionCall) Value {
|
||||
value := call.Argument(0)
|
||||
if !value.IsObject() {
|
||||
return FalseValue()
|
||||
return falseValue
|
||||
}
|
||||
prototype := call.toObject(value).prototype
|
||||
thisObject := call.thisObject()
|
||||
for prototype != nil {
|
||||
if thisObject == prototype {
|
||||
return TrueValue()
|
||||
return trueValue
|
||||
}
|
||||
prototype = prototype.prototype
|
||||
}
|
||||
return FalseValue()
|
||||
return falseValue
|
||||
}
|
||||
|
||||
func builtinObject_propertyIsEnumerable(call FunctionCall) Value {
|
||||
propertyName := toString(call.Argument(0))
|
||||
propertyName := call.Argument(0).string()
|
||||
thisObject := call.thisObject()
|
||||
property := thisObject.getOwnProperty(propertyName)
|
||||
if property != nil && property.enumerable() {
|
||||
return TrueValue()
|
||||
return trueValue
|
||||
}
|
||||
return FalseValue()
|
||||
return falseValue
|
||||
}
|
||||
|
||||
func builtinObject_toString(call FunctionCall) Value {
|
||||
|
|
@ -80,20 +80,20 @@ func builtinObject_toString(call FunctionCall) Value {
|
|||
func builtinObject_toLocaleString(call FunctionCall) Value {
|
||||
toString := call.thisObject().get("toString")
|
||||
if !toString.isCallable() {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
return toString.call(call.This)
|
||||
return toString.call(call.runtime, call.This)
|
||||
}
|
||||
|
||||
func builtinObject_getPrototypeOf(call FunctionCall) Value {
|
||||
objectValue := call.Argument(0)
|
||||
object := objectValue._object()
|
||||
if object == nil {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
if object.prototype == nil {
|
||||
return NullValue()
|
||||
return nullValue
|
||||
}
|
||||
|
||||
return toValue_object(object.prototype)
|
||||
|
|
@ -103,13 +103,13 @@ func builtinObject_getOwnPropertyDescriptor(call FunctionCall) Value {
|
|||
objectValue := call.Argument(0)
|
||||
object := objectValue._object()
|
||||
if object == nil {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
name := toString(call.Argument(1))
|
||||
name := call.Argument(1).string()
|
||||
descriptor := object.getOwnProperty(name)
|
||||
if descriptor == nil {
|
||||
return UndefinedValue()
|
||||
return Value{}
|
||||
}
|
||||
return toValue_object(call.runtime.fromPropertyDescriptor(*descriptor))
|
||||
}
|
||||
|
|
@ -118,10 +118,10 @@ func builtinObject_defineProperty(call FunctionCall) Value {
|
|||
objectValue := call.Argument(0)
|
||||
object := objectValue._object()
|
||||
if object == nil {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
name := toString(call.Argument(1))
|
||||
descriptor := toPropertyDescriptor(call.Argument(2))
|
||||
name := call.Argument(1).string()
|
||||
descriptor := toPropertyDescriptor(call.runtime, call.Argument(2))
|
||||
object.defineOwnProperty(name, descriptor, true)
|
||||
return objectValue
|
||||
}
|
||||
|
|
@ -130,12 +130,12 @@ func builtinObject_defineProperties(call FunctionCall) Value {
|
|||
objectValue := call.Argument(0)
|
||||
object := objectValue._object()
|
||||
if object == nil {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
properties := call.runtime.toObject(call.Argument(1))
|
||||
properties.enumerate(false, func(name string) bool {
|
||||
descriptor := toPropertyDescriptor(properties.get(name))
|
||||
descriptor := toPropertyDescriptor(call.runtime, properties.get(name))
|
||||
object.defineOwnProperty(name, descriptor, true)
|
||||
return true
|
||||
})
|
||||
|
|
@ -146,7 +146,7 @@ func builtinObject_defineProperties(call FunctionCall) Value {
|
|||
func builtinObject_create(call FunctionCall) Value {
|
||||
prototypeValue := call.Argument(0)
|
||||
if !prototypeValue.IsNull() && !prototypeValue.IsObject() {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
object := call.runtime.newObject()
|
||||
|
|
@ -156,7 +156,7 @@ func builtinObject_create(call FunctionCall) Value {
|
|||
if propertiesValue.IsDefined() {
|
||||
properties := call.runtime.toObject(propertiesValue)
|
||||
properties.enumerate(false, func(name string) bool {
|
||||
descriptor := toPropertyDescriptor(properties.get(name))
|
||||
descriptor := toPropertyDescriptor(call.runtime, properties.get(name))
|
||||
object.defineOwnProperty(name, descriptor, true)
|
||||
return true
|
||||
})
|
||||
|
|
@ -170,7 +170,7 @@ func builtinObject_isExtensible(call FunctionCall) Value {
|
|||
if object := object._object(); object != nil {
|
||||
return toValue_bool(object.extensible)
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
func builtinObject_preventExtensions(call FunctionCall) Value {
|
||||
|
|
@ -178,7 +178,7 @@ func builtinObject_preventExtensions(call FunctionCall) Value {
|
|||
if object := object._object(); object != nil {
|
||||
object.extensible = false
|
||||
} else {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
return object
|
||||
}
|
||||
|
|
@ -199,7 +199,7 @@ func builtinObject_isSealed(call FunctionCall) Value {
|
|||
})
|
||||
return toValue_bool(result)
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
func builtinObject_seal(call FunctionCall) Value {
|
||||
|
|
@ -214,7 +214,7 @@ func builtinObject_seal(call FunctionCall) Value {
|
|||
})
|
||||
object.extensible = false
|
||||
} else {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
return object
|
||||
}
|
||||
|
|
@ -235,7 +235,7 @@ func builtinObject_isFrozen(call FunctionCall) Value {
|
|||
})
|
||||
return toValue_bool(result)
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
func builtinObject_freeze(call FunctionCall) Value {
|
||||
|
|
@ -259,7 +259,7 @@ func builtinObject_freeze(call FunctionCall) Value {
|
|||
})
|
||||
object.extensible = false
|
||||
} else {
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
return object
|
||||
}
|
||||
|
|
@ -272,7 +272,7 @@ func builtinObject_keys(call FunctionCall) Value {
|
|||
})
|
||||
return toValue_object(call.runtime.newArrayOf(keys))
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
func builtinObject_getOwnPropertyNames(call FunctionCall) Value {
|
||||
|
|
@ -285,5 +285,5 @@ func builtinObject_getOwnPropertyNames(call FunctionCall) Value {
|
|||
})
|
||||
return toValue_object(call.runtime.newArrayOf(propertyNames))
|
||||
}
|
||||
panic(newTypeError())
|
||||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ func builtinRegExp(call FunctionCall) Value {
|
|||
return toValue_object(call.runtime.newRegExp(pattern, flags))
|
||||
}
|
||||
|
||||
func builtinNewRegExp(self *_object, _ Value, argumentList []Value) Value {
|
||||
func builtinNewRegExp(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newRegExp(
|
||||
valueOfArrayIndex(argumentList, 0),
|
||||
valueOfArrayIndex(argumentList, 1),
|
||||
|
|
@ -26,15 +26,15 @@ func builtinNewRegExp(self *_object, _ Value, argumentList []Value) Value {
|
|||
|
||||
func builtinRegExp_toString(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
source := toString(thisObject.get("source"))
|
||||
source := thisObject.get("source").string()
|
||||
flags := []byte{}
|
||||
if toBoolean(thisObject.get("global")) {
|
||||
if thisObject.get("global").bool() {
|
||||
flags = append(flags, 'g')
|
||||
}
|
||||
if toBoolean(thisObject.get("ignoreCase")) {
|
||||
if thisObject.get("ignoreCase").bool() {
|
||||
flags = append(flags, 'i')
|
||||
}
|
||||
if toBoolean(thisObject.get("multiline")) {
|
||||
if thisObject.get("multiline").bool() {
|
||||
flags = append(flags, 'm')
|
||||
}
|
||||
return toValue_string(fmt.Sprintf("/%s/%s", source, flags))
|
||||
|
|
@ -42,17 +42,17 @@ func builtinRegExp_toString(call FunctionCall) Value {
|
|||
|
||||
func builtinRegExp_exec(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
target := toString(call.Argument(0))
|
||||
target := call.Argument(0).string()
|
||||
match, result := execRegExp(thisObject, target)
|
||||
if !match {
|
||||
return NullValue()
|
||||
return nullValue
|
||||
}
|
||||
return toValue_object(execResultToArray(call.runtime, target, result))
|
||||
}
|
||||
|
||||
func builtinRegExp_test(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
target := toString(call.Argument(0))
|
||||
target := call.Argument(0).string()
|
||||
match, _ := execRegExp(thisObject, target)
|
||||
return toValue_bool(match)
|
||||
}
|
||||
|
|
@ -61,5 +61,5 @@ func builtinRegExp_compile(call FunctionCall) Value {
|
|||
// This (useless) function is deprecated, but is here to provide some
|
||||
// semblance of compatibility.
|
||||
// Caveat emptor: it may not be around for long.
|
||||
return UndefinedValue()
|
||||
return Value{}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ import (
|
|||
|
||||
func stringValueFromStringArgumentList(argumentList []Value) Value {
|
||||
if len(argumentList) > 0 {
|
||||
return toValue_string(toString(argumentList[0]))
|
||||
return toValue_string(argumentList[0].string())
|
||||
}
|
||||
return toValue_string("")
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ func builtinString(call FunctionCall) Value {
|
|||
return stringValueFromStringArgumentList(call.ArgumentList)
|
||||
}
|
||||
|
||||
func builtinNewString(self *_object, _ Value, argumentList []Value) Value {
|
||||
func builtinNewString(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newString(stringValueFromStringArgumentList(argumentList)))
|
||||
}
|
||||
|
||||
|
|
@ -41,8 +41,8 @@ func builtinString_fromCharCode(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinString_charAt(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
idx := int(toInteger(call.Argument(0)).value)
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
idx := int(call.Argument(0).number().int64)
|
||||
chr := stringAt(call.This._object().stringValue(), idx)
|
||||
if chr == utf8.RuneError {
|
||||
return toValue_string("")
|
||||
|
|
@ -51,8 +51,8 @@ func builtinString_charAt(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinString_charCodeAt(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
idx := int(toInteger(call.Argument(0)).value)
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
idx := int(call.Argument(0).number().int64)
|
||||
chr := stringAt(call.This._object().stringValue(), idx)
|
||||
if chr == utf8.RuneError {
|
||||
return NaNValue()
|
||||
|
|
@ -61,19 +61,19 @@ func builtinString_charCodeAt(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinString_concat(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
var value bytes.Buffer
|
||||
value.WriteString(toString(call.This))
|
||||
value.WriteString(call.This.string())
|
||||
for _, item := range call.ArgumentList {
|
||||
value.WriteString(toString(item))
|
||||
value.WriteString(item.string())
|
||||
}
|
||||
return toValue_string(value.String())
|
||||
}
|
||||
|
||||
func builtinString_indexOf(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
value := toString(call.This)
|
||||
target := toString(call.Argument(0))
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
value := call.This.string()
|
||||
target := call.Argument(0).string()
|
||||
if 2 > len(call.ArgumentList) {
|
||||
return toValue_int(strings.Index(value, target))
|
||||
}
|
||||
|
|
@ -94,9 +94,9 @@ func builtinString_indexOf(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinString_lastIndexOf(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
value := toString(call.This)
|
||||
target := toString(call.Argument(0))
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
value := call.This.string()
|
||||
target := call.Argument(0).string()
|
||||
if 2 > len(call.ArgumentList) || call.ArgumentList[1].IsUndefined() {
|
||||
return toValue_int(strings.LastIndex(value, target))
|
||||
}
|
||||
|
|
@ -104,15 +104,15 @@ func builtinString_lastIndexOf(call FunctionCall) Value {
|
|||
if length == 0 {
|
||||
return toValue_int(strings.LastIndex(value, target))
|
||||
}
|
||||
start := toInteger(call.ArgumentList[1])
|
||||
if !start.valid() {
|
||||
start := call.ArgumentList[1].number()
|
||||
if start.kind == numberInfinity { // FIXME
|
||||
// startNumber is infinity, so start is the end of string (start = length)
|
||||
return toValue_int(strings.LastIndex(value, target))
|
||||
}
|
||||
if 0 > start.value {
|
||||
start.value = 0
|
||||
if 0 > start.int64 {
|
||||
start.int64 = 0
|
||||
}
|
||||
end := int(start.value) + len(target)
|
||||
end := int(start.int64) + len(target)
|
||||
if end > length {
|
||||
end = length
|
||||
}
|
||||
|
|
@ -120,18 +120,18 @@ func builtinString_lastIndexOf(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinString_match(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
target := toString(call.This)
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
target := call.This.string()
|
||||
matcherValue := call.Argument(0)
|
||||
matcher := matcherValue._object()
|
||||
if !matcherValue.IsObject() || matcher.class != "RegExp" {
|
||||
matcher = call.runtime.newRegExp(matcherValue, UndefinedValue())
|
||||
matcher = call.runtime.newRegExp(matcherValue, Value{})
|
||||
}
|
||||
global := toBoolean(matcher.get("global"))
|
||||
global := matcher.get("global").bool()
|
||||
if !global {
|
||||
match, result := execRegExp(matcher, target)
|
||||
if !match {
|
||||
return NullValue()
|
||||
return nullValue
|
||||
}
|
||||
return toValue_object(execResultToArray(call.runtime, target, result))
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ func builtinString_match(call FunctionCall) Value {
|
|||
matchCount := len(result)
|
||||
if result == nil {
|
||||
matcher.put("lastIndex", toValue_int(0), true)
|
||||
return UndefinedValue() // !match
|
||||
return Value{} // !match
|
||||
}
|
||||
matchCount = len(result)
|
||||
valueArray := make([]Value, matchCount)
|
||||
|
|
@ -189,8 +189,8 @@ func builtinString_findAndReplaceString(input []byte, lastIndex int, match []int
|
|||
}
|
||||
|
||||
func builtinString_replace(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
target := []byte(toString(call.This))
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
target := []byte(call.This.string())
|
||||
searchValue := call.Argument(0)
|
||||
searchObject := searchValue._object()
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ func builtinString_replace(call FunctionCall) Value {
|
|||
find = -1
|
||||
}
|
||||
} else {
|
||||
search = regexp.MustCompile(regexp.QuoteMeta(toString(searchValue)))
|
||||
search = regexp.MustCompile(regexp.QuoteMeta(searchValue.string()))
|
||||
}
|
||||
|
||||
found := search.FindAllSubmatchIndex(target, find)
|
||||
|
|
@ -232,18 +232,18 @@ func builtinString_replace(call FunctionCall) Value {
|
|||
if match[offset] != -1 {
|
||||
argumentList[index] = toValue_string(target[match[offset]:match[offset+1]])
|
||||
} else {
|
||||
argumentList[index] = UndefinedValue()
|
||||
argumentList[index] = Value{}
|
||||
}
|
||||
}
|
||||
argumentList[matchCount+0] = toValue_int(match[0])
|
||||
argumentList[matchCount+1] = toValue_string(target)
|
||||
replacement := toString(replace.Call(UndefinedValue(), argumentList))
|
||||
replacement := replace.call(Value{}, argumentList, false, nativeFrame).string()
|
||||
result = append(result, []byte(replacement)...)
|
||||
lastIndex = match[1]
|
||||
}
|
||||
|
||||
} else {
|
||||
replace := []byte(toString(replaceValue))
|
||||
replace := []byte(replaceValue.string())
|
||||
for _, match := range found {
|
||||
result = builtinString_findAndReplaceString(result, lastIndex, match, target, replace)
|
||||
lastIndex = match[1]
|
||||
|
|
@ -260,17 +260,15 @@ func builtinString_replace(call FunctionCall) Value {
|
|||
|
||||
return toValue_string(string(result))
|
||||
}
|
||||
|
||||
return UndefinedValue()
|
||||
}
|
||||
|
||||
func builtinString_search(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
target := toString(call.This)
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
target := call.This.string()
|
||||
searchValue := call.Argument(0)
|
||||
search := searchValue._object()
|
||||
if !searchValue.IsObject() || search.class != "RegExp" {
|
||||
search = call.runtime.newRegExp(searchValue, UndefinedValue())
|
||||
search = call.runtime.newRegExp(searchValue, Value{})
|
||||
}
|
||||
result := search.regExpValue().regularExpression.FindStringIndex(target)
|
||||
if result == nil {
|
||||
|
|
@ -291,8 +289,8 @@ func stringSplitMatch(target string, targetLength int64, index uint, search stri
|
|||
}
|
||||
|
||||
func builtinString_split(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
target := toString(call.This)
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
target := call.This.string()
|
||||
|
||||
separatorValue := call.Argument(0)
|
||||
limitValue := call.Argument(1)
|
||||
|
|
@ -343,7 +341,7 @@ func builtinString_split(call FunctionCall) Value {
|
|||
captureCount := len(match) / 2
|
||||
for index := 1; index < captureCount; index++ {
|
||||
offset := index * 2
|
||||
value := UndefinedValue()
|
||||
value := Value{}
|
||||
if match[offset] != -1 {
|
||||
value = toValue_string(target[match[offset]:match[offset+1]])
|
||||
}
|
||||
|
|
@ -367,7 +365,7 @@ func builtinString_split(call FunctionCall) Value {
|
|||
return toValue_object(call.runtime.newArrayOf(valueArray))
|
||||
|
||||
} else {
|
||||
separator := toString(separatorValue)
|
||||
separator := separatorValue.string()
|
||||
|
||||
splitLimit := limit
|
||||
excess := false
|
||||
|
|
@ -389,13 +387,11 @@ func builtinString_split(call FunctionCall) Value {
|
|||
|
||||
return toValue_object(call.runtime.newArrayOf(valueArray))
|
||||
}
|
||||
|
||||
return UndefinedValue()
|
||||
}
|
||||
|
||||
func builtinString_slice(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
target := toString(call.This)
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
target := call.This.string()
|
||||
|
||||
length := int64(len(target))
|
||||
start, end := rangeStartEnd(call.ArgumentList, length, false)
|
||||
|
|
@ -406,8 +402,8 @@ func builtinString_slice(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinString_substring(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
target := toString(call.This)
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
target := call.This.string()
|
||||
|
||||
length := int64(len(target))
|
||||
start, end := rangeStartEnd(call.ArgumentList, length, true)
|
||||
|
|
@ -418,7 +414,7 @@ func builtinString_substring(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinString_substr(call FunctionCall) Value {
|
||||
target := toString(call.This)
|
||||
target := call.This.string()
|
||||
|
||||
size := int64(len(target))
|
||||
start, length := rangeStartLength(call.ArgumentList, size)
|
||||
|
|
@ -443,42 +439,42 @@ func builtinString_substr(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinString_toLowerCase(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
return toValue_string(strings.ToLower(toString(call.This)))
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
return toValue_string(strings.ToLower(call.This.string()))
|
||||
}
|
||||
|
||||
func builtinString_toUpperCase(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
return toValue_string(strings.ToUpper(toString(call.This)))
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
return toValue_string(strings.ToUpper(call.This.string()))
|
||||
}
|
||||
|
||||
// 7.2 Table 2 — Whitespace Characters & 7.3 Table 3 - Line Terminator Characters
|
||||
const builtinString_trim_whitespace = "\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF"
|
||||
|
||||
func builtinString_trim(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
return toValue(strings.Trim(toString(call.This),
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
return toValue(strings.Trim(call.This.string(),
|
||||
builtinString_trim_whitespace))
|
||||
}
|
||||
|
||||
// Mozilla extension, not ECMAScript 5
|
||||
func builtinString_trimLeft(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
return toValue(strings.TrimLeft(toString(call.This),
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
return toValue(strings.TrimLeft(call.This.string(),
|
||||
builtinString_trim_whitespace))
|
||||
}
|
||||
|
||||
// Mozilla extension, not ECMAScript 5
|
||||
func builtinString_trimRight(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
return toValue(strings.TrimRight(toString(call.This),
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
return toValue(strings.TrimRight(call.This.string(),
|
||||
builtinString_trim_whitespace))
|
||||
}
|
||||
|
||||
func builtinString_localeCompare(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
this := toString(call.This)
|
||||
that := toString(call.Argument(0))
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
this := call.This.string()
|
||||
that := call.Argument(0).string()
|
||||
if this < that {
|
||||
return toValue_int(-1)
|
||||
} else if this == that {
|
||||
|
|
@ -491,7 +487,7 @@ func builtinString_localeCompare(call FunctionCall) Value {
|
|||
An alternate version of String.trim
|
||||
func builtinString_trim(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.This)
|
||||
return toValue_string(strings.TrimFunc(toString(call.This), isWhiteSpaceOrLineTerminator))
|
||||
return toValue_string(strings.TrimFunc(call.string(.This), isWhiteSpaceOrLineTerminator))
|
||||
}
|
||||
*/
|
||||
|
||||
155
Godeps/_workspace/src/github.com/robertkrimen/otto/clone.go
generated
vendored
Normal file
155
Godeps/_workspace/src/github.com/robertkrimen/otto/clone.go
generated
vendored
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type _clone struct {
|
||||
runtime *_runtime
|
||||
_object map[*_object]*_object
|
||||
_objectStash map[*_objectStash]*_objectStash
|
||||
_dclStash map[*_dclStash]*_dclStash
|
||||
_fnStash map[*_fnStash]*_fnStash
|
||||
}
|
||||
|
||||
func (in *_runtime) clone() *_runtime {
|
||||
|
||||
in.lck.Lock()
|
||||
defer in.lck.Unlock()
|
||||
|
||||
out := &_runtime{}
|
||||
clone := _clone{
|
||||
runtime: out,
|
||||
_object: make(map[*_object]*_object),
|
||||
_objectStash: make(map[*_objectStash]*_objectStash),
|
||||
_dclStash: make(map[*_dclStash]*_dclStash),
|
||||
_fnStash: make(map[*_fnStash]*_fnStash),
|
||||
}
|
||||
|
||||
globalObject := clone.object(in.globalObject)
|
||||
out.globalStash = out.newObjectStash(globalObject, nil)
|
||||
out.globalObject = globalObject
|
||||
out.global = _global{
|
||||
clone.object(in.global.Object),
|
||||
clone.object(in.global.Function),
|
||||
clone.object(in.global.Array),
|
||||
clone.object(in.global.String),
|
||||
clone.object(in.global.Boolean),
|
||||
clone.object(in.global.Number),
|
||||
clone.object(in.global.Math),
|
||||
clone.object(in.global.Date),
|
||||
clone.object(in.global.RegExp),
|
||||
clone.object(in.global.Error),
|
||||
clone.object(in.global.EvalError),
|
||||
clone.object(in.global.TypeError),
|
||||
clone.object(in.global.RangeError),
|
||||
clone.object(in.global.ReferenceError),
|
||||
clone.object(in.global.SyntaxError),
|
||||
clone.object(in.global.URIError),
|
||||
clone.object(in.global.JSON),
|
||||
|
||||
clone.object(in.global.ObjectPrototype),
|
||||
clone.object(in.global.FunctionPrototype),
|
||||
clone.object(in.global.ArrayPrototype),
|
||||
clone.object(in.global.StringPrototype),
|
||||
clone.object(in.global.BooleanPrototype),
|
||||
clone.object(in.global.NumberPrototype),
|
||||
clone.object(in.global.DatePrototype),
|
||||
clone.object(in.global.RegExpPrototype),
|
||||
clone.object(in.global.ErrorPrototype),
|
||||
clone.object(in.global.EvalErrorPrototype),
|
||||
clone.object(in.global.TypeErrorPrototype),
|
||||
clone.object(in.global.RangeErrorPrototype),
|
||||
clone.object(in.global.ReferenceErrorPrototype),
|
||||
clone.object(in.global.SyntaxErrorPrototype),
|
||||
clone.object(in.global.URIErrorPrototype),
|
||||
}
|
||||
|
||||
out.eval = out.globalObject.property["eval"].value.(Value).value.(*_object)
|
||||
out.globalObject.prototype = out.global.ObjectPrototype
|
||||
|
||||
// Not sure if this is necessary, but give some help to the GC
|
||||
clone.runtime = nil
|
||||
clone._object = nil
|
||||
clone._objectStash = nil
|
||||
clone._dclStash = nil
|
||||
clone._fnStash = nil
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (clone *_clone) object(in *_object) *_object {
|
||||
if out, exists := clone._object[in]; exists {
|
||||
return out
|
||||
}
|
||||
out := &_object{}
|
||||
clone._object[in] = out
|
||||
return in.objectClass.clone(in, out, clone)
|
||||
}
|
||||
|
||||
func (clone *_clone) dclStash(in *_dclStash) (*_dclStash, bool) {
|
||||
if out, exists := clone._dclStash[in]; exists {
|
||||
return out, true
|
||||
}
|
||||
out := &_dclStash{}
|
||||
clone._dclStash[in] = out
|
||||
return out, false
|
||||
}
|
||||
|
||||
func (clone *_clone) objectStash(in *_objectStash) (*_objectStash, bool) {
|
||||
if out, exists := clone._objectStash[in]; exists {
|
||||
return out, true
|
||||
}
|
||||
out := &_objectStash{}
|
||||
clone._objectStash[in] = out
|
||||
return out, false
|
||||
}
|
||||
|
||||
func (clone *_clone) fnStash(in *_fnStash) (*_fnStash, bool) {
|
||||
if out, exists := clone._fnStash[in]; exists {
|
||||
return out, true
|
||||
}
|
||||
out := &_fnStash{}
|
||||
clone._fnStash[in] = out
|
||||
return out, false
|
||||
}
|
||||
|
||||
func (clone *_clone) value(in Value) Value {
|
||||
out := in
|
||||
switch value := in.value.(type) {
|
||||
case *_object:
|
||||
out.value = clone.object(value)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (clone *_clone) valueArray(in []Value) []Value {
|
||||
out := make([]Value, len(in))
|
||||
for index, value := range in {
|
||||
out[index] = clone.value(value)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (clone *_clone) stash(in _stash) _stash {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
return in.clone(clone)
|
||||
}
|
||||
|
||||
func (clone *_clone) property(in _property) _property {
|
||||
out := in
|
||||
if value, valid := in.value.(Value); valid {
|
||||
out.value = clone.value(value)
|
||||
} else {
|
||||
panic(fmt.Errorf("in.value.(Value) != true"))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (clone *_clone) dclProperty(in _dclProperty) _dclProperty {
|
||||
out := in
|
||||
out.value = clone.value(in.value)
|
||||
return out
|
||||
}
|
||||
24
Godeps/_workspace/src/github.com/robertkrimen/otto/cmpl.go
generated
vendored
Normal file
24
Godeps/_workspace/src/github.com/robertkrimen/otto/cmpl.go
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
"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
|
||||
}
|
||||
|
||||
func (cmpl *_compiler) parse() *_nodeProgram {
|
||||
if cmpl.program != nil {
|
||||
cmpl.file = cmpl.program.File
|
||||
}
|
||||
return cmpl._parse(cmpl.program)
|
||||
}
|
||||
|
|
@ -4,13 +4,20 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
func (self *_runtime) cmpl_evaluate_nodeProgram(node *_nodeProgram) Value {
|
||||
func (self *_runtime) cmpl_evaluate_nodeProgram(node *_nodeProgram, eval bool) Value {
|
||||
if !eval {
|
||||
self.enterGlobalScope()
|
||||
defer func() {
|
||||
self.leaveScope()
|
||||
}()
|
||||
}
|
||||
self.cmpl_functionDeclaration(node.functionList)
|
||||
self.cmpl_variableDeclaration(node.varList)
|
||||
self.scope.frame.file = node.file
|
||||
return self.cmpl_evaluate_nodeStatementList(node.body)
|
||||
}
|
||||
|
||||
func (self *_runtime) cmpl_call_nodeFunction(function *_object, environment *_functionEnvironment, node *_nodeFunctionLiteral, this Value, argumentList []Value) Value {
|
||||
func (self *_runtime) cmpl_call_nodeFunction(function *_object, stash *_fnStash, node *_nodeFunctionLiteral, this Value, argumentList []Value) Value {
|
||||
|
||||
indexOfParameterName := make([]string, len(argumentList))
|
||||
// function(abc, def, ghi)
|
||||
|
|
@ -24,19 +31,21 @@ func (self *_runtime) cmpl_call_nodeFunction(function *_object, environment *_fu
|
|||
if name == "arguments" {
|
||||
argumentsFound = true
|
||||
}
|
||||
value := UndefinedValue()
|
||||
value := Value{}
|
||||
if index < len(argumentList) {
|
||||
value = argumentList[index]
|
||||
indexOfParameterName[index] = name
|
||||
}
|
||||
self.localSet(name, value)
|
||||
// strict = false
|
||||
self.scope.lexical.setValue(name, value, false)
|
||||
}
|
||||
|
||||
if !argumentsFound {
|
||||
arguments := self.newArgumentsObject(indexOfParameterName, environment, len(argumentList))
|
||||
arguments := self.newArgumentsObject(indexOfParameterName, stash, len(argumentList))
|
||||
arguments.defineProperty("callee", toValue_object(function), 0101, false)
|
||||
environment.arguments = arguments
|
||||
self.localSet("arguments", toValue_object(arguments))
|
||||
stash.arguments = arguments
|
||||
// strict = false
|
||||
self.scope.lexical.setValue("arguments", toValue_object(arguments), false)
|
||||
for index, _ := range argumentList {
|
||||
if index < len(node.parameterList) {
|
||||
continue
|
||||
|
|
@ -50,38 +59,38 @@ func (self *_runtime) cmpl_call_nodeFunction(function *_object, environment *_fu
|
|||
self.cmpl_variableDeclaration(node.varList)
|
||||
|
||||
result := self.cmpl_evaluate_nodeStatement(node.body)
|
||||
if result.isResult() {
|
||||
if result.kind == valueResult {
|
||||
return result
|
||||
}
|
||||
|
||||
return UndefinedValue()
|
||||
return Value{}
|
||||
}
|
||||
|
||||
func (self *_runtime) cmpl_functionDeclaration(list []*_nodeFunctionLiteral) {
|
||||
executionContext := self._executionContext(0)
|
||||
executionContext := self.scope
|
||||
eval := executionContext.eval
|
||||
environment := executionContext.VariableEnvironment
|
||||
stash := executionContext.variable
|
||||
|
||||
for _, function := range list {
|
||||
name := function.name
|
||||
value := self.cmpl_evaluate_nodeExpression(function)
|
||||
if !environment.HasBinding(name) {
|
||||
environment.CreateMutableBinding(name, eval == true)
|
||||
}
|
||||
if !stash.hasBinding(name) {
|
||||
stash.createBinding(name, eval == true, value)
|
||||
} else {
|
||||
// TODO 10.5.5.e
|
||||
environment.SetMutableBinding(name, value, false) // TODO strict
|
||||
stash.setBinding(name, value, false) // TODO strict
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_runtime) cmpl_variableDeclaration(list []string) {
|
||||
executionContext := self._executionContext(0)
|
||||
executionContext := self.scope
|
||||
eval := executionContext.eval
|
||||
environment := executionContext.VariableEnvironment
|
||||
stash := executionContext.variable
|
||||
|
||||
for _, name := range list {
|
||||
if !environment.HasBinding(name) {
|
||||
environment.CreateMutableBinding(name, eval == true)
|
||||
environment.SetMutableBinding(name, UndefinedValue(), false) // TODO strict
|
||||
if !stash.hasBinding(name) {
|
||||
stash.createBinding(name, eval == true, Value{}) // TODO strict?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,10 +13,10 @@ func (self *_runtime) cmpl_evaluate_nodeExpression(node _nodeExpression) Value {
|
|||
// If the Interrupt channel is nil, then
|
||||
// we avoid runtime.Gosched() overhead (if any)
|
||||
// FIXME: Test this
|
||||
if self.Otto.Interrupt != nil {
|
||||
if self.otto.Interrupt != nil {
|
||||
runtime.Gosched()
|
||||
select {
|
||||
case value := <-self.Otto.Interrupt:
|
||||
case value := <-self.otto.Interrupt:
|
||||
value()
|
||||
default:
|
||||
}
|
||||
|
|
@ -50,15 +50,14 @@ func (self *_runtime) cmpl_evaluate_nodeExpression(node _nodeExpression) Value {
|
|||
return self.cmpl_evaluate_nodeDotExpression(node)
|
||||
|
||||
case *_nodeFunctionLiteral:
|
||||
var local = self.LexicalEnvironment()
|
||||
var local = self.scope.lexical
|
||||
if node.name != "" {
|
||||
local = self.newDeclarativeEnvironment(local)
|
||||
local = self.newDeclarationStash(local)
|
||||
}
|
||||
|
||||
value := toValue_object(self.newNodeFunction(node, local))
|
||||
if node.name != "" {
|
||||
local.CreateMutableBinding(node.name, false)
|
||||
local.SetMutableBinding(node.name, value, false)
|
||||
local.createBinding(node.name, false, value)
|
||||
}
|
||||
return value
|
||||
|
||||
|
|
@ -67,7 +66,7 @@ func (self *_runtime) cmpl_evaluate_nodeExpression(node _nodeExpression) Value {
|
|||
// TODO Should be true or false (strictness) depending on context
|
||||
// getIdentifierReference should not return nil, but we check anyway and panic
|
||||
// so as not to propagate the nil into something else
|
||||
reference := getIdentifierReference(self.LexicalEnvironment(), name, false)
|
||||
reference := getIdentifierReference(self, self.scope.lexical, name, false, _at(node.idx))
|
||||
if reference == nil {
|
||||
// Should never get here!
|
||||
panic(hereBeDragons("referenceError == nil: " + name))
|
||||
|
|
@ -90,7 +89,7 @@ func (self *_runtime) cmpl_evaluate_nodeExpression(node _nodeExpression) Value {
|
|||
return self.cmpl_evaluate_nodeSequenceExpression(node)
|
||||
|
||||
case *_nodeThisExpression:
|
||||
return toValue_object(self._executionContext(0).this)
|
||||
return toValue_object(self.scope.this)
|
||||
|
||||
case *_nodeUnaryExpression:
|
||||
return self.cmpl_evaluate_nodeUnaryExpression(node)
|
||||
|
|
@ -108,9 +107,9 @@ func (self *_runtime) cmpl_evaluate_nodeArrayLiteral(node *_nodeArrayLiteral) Va
|
|||
|
||||
for _, node := range node.value {
|
||||
if node == nil {
|
||||
valueArray = append(valueArray, Value{})
|
||||
valueArray = append(valueArray, emptyValue)
|
||||
} else {
|
||||
valueArray = append(valueArray, self.GetValue(self.cmpl_evaluate_nodeExpression(node)))
|
||||
valueArray = append(valueArray, self.cmpl_evaluate_nodeExpression(node).resolve())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,14 +122,14 @@ func (self *_runtime) cmpl_evaluate_nodeAssignExpression(node *_nodeAssignExpres
|
|||
|
||||
left := self.cmpl_evaluate_nodeExpression(node.left)
|
||||
right := self.cmpl_evaluate_nodeExpression(node.right)
|
||||
rightValue := self.GetValue(right)
|
||||
rightValue := right.resolve()
|
||||
|
||||
result := rightValue
|
||||
if node.operator != token.ASSIGN {
|
||||
result = self.calculateBinaryExpression(node.operator, left, rightValue)
|
||||
}
|
||||
|
||||
self.PutValue(left.reference(), result)
|
||||
self.putValue(left.reference(), result)
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
@ -138,22 +137,22 @@ func (self *_runtime) cmpl_evaluate_nodeAssignExpression(node *_nodeAssignExpres
|
|||
func (self *_runtime) cmpl_evaluate_nodeBinaryExpression(node *_nodeBinaryExpression) Value {
|
||||
|
||||
left := self.cmpl_evaluate_nodeExpression(node.left)
|
||||
leftValue := self.GetValue(left)
|
||||
leftValue := left.resolve()
|
||||
|
||||
switch node.operator {
|
||||
// Logical
|
||||
case token.LOGICAL_AND:
|
||||
if !toBoolean(leftValue) {
|
||||
if !leftValue.bool() {
|
||||
return leftValue
|
||||
}
|
||||
right := self.cmpl_evaluate_nodeExpression(node.right)
|
||||
return self.GetValue(right)
|
||||
return right.resolve()
|
||||
case token.LOGICAL_OR:
|
||||
if toBoolean(leftValue) {
|
||||
if leftValue.bool() {
|
||||
return leftValue
|
||||
}
|
||||
right := self.cmpl_evaluate_nodeExpression(node.right)
|
||||
return self.GetValue(right)
|
||||
return right.resolve()
|
||||
}
|
||||
|
||||
return self.calculateBinaryExpression(node.operator, leftValue, self.cmpl_evaluate_nodeExpression(node.right))
|
||||
|
|
@ -161,57 +160,90 @@ func (self *_runtime) cmpl_evaluate_nodeBinaryExpression(node *_nodeBinaryExpres
|
|||
|
||||
func (self *_runtime) cmpl_evaluate_nodeBinaryExpression_comparison(node *_nodeBinaryExpression) Value {
|
||||
|
||||
left := self.GetValue(self.cmpl_evaluate_nodeExpression(node.left))
|
||||
right := self.GetValue(self.cmpl_evaluate_nodeExpression(node.right))
|
||||
left := self.cmpl_evaluate_nodeExpression(node.left).resolve()
|
||||
right := self.cmpl_evaluate_nodeExpression(node.right).resolve()
|
||||
|
||||
return toValue_bool(self.calculateComparison(node.operator, left, right))
|
||||
}
|
||||
|
||||
func (self *_runtime) cmpl_evaluate_nodeBracketExpression(node *_nodeBracketExpression) Value {
|
||||
target := self.cmpl_evaluate_nodeExpression(node.left)
|
||||
targetValue := self.GetValue(target)
|
||||
targetValue := target.resolve()
|
||||
member := self.cmpl_evaluate_nodeExpression(node.member)
|
||||
memberValue := self.GetValue(member)
|
||||
memberValue := member.resolve()
|
||||
|
||||
// TODO Pass in base value as-is, and defer toObject till later?
|
||||
return toValue(newPropertyReference(self.toObject(targetValue), toString(memberValue), false))
|
||||
return toValue(newPropertyReference(self, self.toObject(targetValue), memberValue.string(), false, _at(node.idx)))
|
||||
}
|
||||
|
||||
func (self *_runtime) cmpl_evaluate_nodeCallExpression(node *_nodeCallExpression, withArgumentList []interface{}) Value {
|
||||
rt := self
|
||||
this := Value{}
|
||||
callee := self.cmpl_evaluate_nodeExpression(node.callee)
|
||||
calleeValue := self.GetValue(callee)
|
||||
|
||||
argumentList := []Value{}
|
||||
if withArgumentList != nil {
|
||||
argumentList = self.toValueArray(withArgumentList...)
|
||||
} else {
|
||||
for _, argumentNode := range node.argumentList {
|
||||
argumentList = append(argumentList, self.GetValue(self.cmpl_evaluate_nodeExpression(argumentNode)))
|
||||
argumentList = append(argumentList, self.cmpl_evaluate_nodeExpression(argumentNode).resolve())
|
||||
}
|
||||
}
|
||||
this := UndefinedValue()
|
||||
calleeReference := callee.reference()
|
||||
evalHint := false
|
||||
if calleeReference != nil {
|
||||
if calleeReference.IsPropertyReference() {
|
||||
calleeObject := calleeReference.GetBase().(*_object)
|
||||
this = toValue_object(calleeObject)
|
||||
} else {
|
||||
// TODO ImplictThisValue
|
||||
}
|
||||
if calleeReference.GetName() == "eval" {
|
||||
evalHint = true // Possible direct eval
|
||||
|
||||
rf := callee.reference()
|
||||
vl := callee.resolve()
|
||||
|
||||
eval := false // Whether this call is a (candidate for) direct call to eval
|
||||
name := ""
|
||||
if rf != nil {
|
||||
switch rf := rf.(type) {
|
||||
case *_propertyReference:
|
||||
name = rf.name
|
||||
object := rf.base
|
||||
this = toValue_object(object)
|
||||
eval = rf.name == "eval" // Possible direct eval
|
||||
case *_stashReference:
|
||||
// TODO ImplicitThisValue
|
||||
name = rf.name
|
||||
eval = rf.name == "eval" // Possible direct eval
|
||||
default:
|
||||
// FIXME?
|
||||
panic(rt.panicTypeError("Here be dragons"))
|
||||
}
|
||||
}
|
||||
if !calleeValue.IsFunction() {
|
||||
panic(newTypeError("%v is not a function", calleeValue))
|
||||
|
||||
at := _at(-1)
|
||||
switch callee := node.callee.(type) {
|
||||
case *_nodeIdentifier:
|
||||
at = _at(callee.idx)
|
||||
case *_nodeDotExpression:
|
||||
at = _at(callee.idx)
|
||||
case *_nodeBracketExpression:
|
||||
at = _at(callee.idx)
|
||||
}
|
||||
return self.Call(calleeValue._object(), this, argumentList, evalHint)
|
||||
|
||||
frame := _frame{
|
||||
callee: name,
|
||||
file: self.scope.frame.file,
|
||||
}
|
||||
|
||||
if !vl.IsFunction() {
|
||||
if name == "" {
|
||||
// FIXME Maybe typeof?
|
||||
panic(rt.panicTypeError("%v is not a function", vl, at))
|
||||
}
|
||||
panic(rt.panicTypeError("'%s' is not a function", name, at))
|
||||
}
|
||||
|
||||
self.scope.frame.offset = int(at)
|
||||
|
||||
return vl._object().call(this, argumentList, eval, frame)
|
||||
}
|
||||
|
||||
func (self *_runtime) cmpl_evaluate_nodeConditionalExpression(node *_nodeConditionalExpression) Value {
|
||||
test := self.cmpl_evaluate_nodeExpression(node.test)
|
||||
testValue := self.GetValue(test)
|
||||
if toBoolean(testValue) {
|
||||
testValue := test.resolve()
|
||||
if testValue.bool() {
|
||||
return self.cmpl_evaluate_nodeExpression(node.consequent)
|
||||
}
|
||||
return self.cmpl_evaluate_nodeExpression(node.alternate)
|
||||
|
|
@ -219,27 +251,60 @@ func (self *_runtime) cmpl_evaluate_nodeConditionalExpression(node *_nodeConditi
|
|||
|
||||
func (self *_runtime) cmpl_evaluate_nodeDotExpression(node *_nodeDotExpression) Value {
|
||||
target := self.cmpl_evaluate_nodeExpression(node.left)
|
||||
targetValue := self.GetValue(target)
|
||||
targetValue := target.resolve()
|
||||
// TODO Pass in base value as-is, and defer toObject till later?
|
||||
object, err := self.objectCoerce(targetValue)
|
||||
if err != nil {
|
||||
panic(newTypeError(fmt.Sprintf("Cannot access member '%s' of %s", node.identifier, err.Error())))
|
||||
panic(self.panicTypeError("Cannot access member '%s' of %s", node.identifier, err.Error()))
|
||||
}
|
||||
return toValue(newPropertyReference(object, node.identifier, false))
|
||||
return toValue(newPropertyReference(self, object, node.identifier, false, _at(node.idx)))
|
||||
}
|
||||
|
||||
func (self *_runtime) cmpl_evaluate_nodeNewExpression(node *_nodeNewExpression) Value {
|
||||
rt := self
|
||||
callee := self.cmpl_evaluate_nodeExpression(node.callee)
|
||||
calleeValue := self.GetValue(callee)
|
||||
|
||||
argumentList := []Value{}
|
||||
for _, argumentNode := range node.argumentList {
|
||||
argumentList = append(argumentList, self.GetValue(self.cmpl_evaluate_nodeExpression(argumentNode)))
|
||||
argumentList = append(argumentList, self.cmpl_evaluate_nodeExpression(argumentNode).resolve())
|
||||
}
|
||||
this := UndefinedValue()
|
||||
if !calleeValue.IsFunction() {
|
||||
panic(newTypeError("%v is not a function", calleeValue))
|
||||
|
||||
rf := callee.reference()
|
||||
vl := callee.resolve()
|
||||
|
||||
name := ""
|
||||
if rf != nil {
|
||||
switch rf := rf.(type) {
|
||||
case *_propertyReference:
|
||||
name = rf.name
|
||||
case *_stashReference:
|
||||
name = rf.name
|
||||
default:
|
||||
panic(rt.panicTypeError("Here be dragons"))
|
||||
}
|
||||
return calleeValue._object().Construct(this, argumentList)
|
||||
}
|
||||
|
||||
at := _at(-1)
|
||||
switch callee := node.callee.(type) {
|
||||
case *_nodeIdentifier:
|
||||
at = _at(callee.idx)
|
||||
case *_nodeDotExpression:
|
||||
at = _at(callee.idx)
|
||||
case *_nodeBracketExpression:
|
||||
at = _at(callee.idx)
|
||||
}
|
||||
|
||||
if !vl.IsFunction() {
|
||||
if name == "" {
|
||||
// FIXME Maybe typeof?
|
||||
panic(rt.panicTypeError("%v is not a function", vl, at))
|
||||
}
|
||||
panic(rt.panicTypeError("'%s' is not a function", name, at))
|
||||
}
|
||||
|
||||
self.scope.frame.offset = int(at)
|
||||
|
||||
return vl._object().construct(argumentList)
|
||||
}
|
||||
|
||||
func (self *_runtime) cmpl_evaluate_nodeObjectLiteral(node *_nodeObjectLiteral) Value {
|
||||
|
|
@ -249,15 +314,15 @@ func (self *_runtime) cmpl_evaluate_nodeObjectLiteral(node *_nodeObjectLiteral)
|
|||
for _, property := range node.value {
|
||||
switch property.kind {
|
||||
case "value":
|
||||
result.defineProperty(property.key, self.GetValue(self.cmpl_evaluate_nodeExpression(property.value)), 0111, false)
|
||||
result.defineProperty(property.key, self.cmpl_evaluate_nodeExpression(property.value).resolve(), 0111, false)
|
||||
case "get":
|
||||
getter := self.newNodeFunction(property.value.(*_nodeFunctionLiteral), self.LexicalEnvironment())
|
||||
getter := self.newNodeFunction(property.value.(*_nodeFunctionLiteral), self.scope.lexical)
|
||||
descriptor := _property{}
|
||||
descriptor.mode = 0211
|
||||
descriptor.value = _propertyGetSet{getter, nil}
|
||||
result.defineOwnProperty(property.key, descriptor, false)
|
||||
case "set":
|
||||
setter := self.newNodeFunction(property.value.(*_nodeFunctionLiteral), self.LexicalEnvironment())
|
||||
setter := self.newNodeFunction(property.value.(*_nodeFunctionLiteral), self.scope.lexical)
|
||||
descriptor := _property{}
|
||||
descriptor.mode = 0211
|
||||
descriptor.value = _propertyGetSet{nil, setter}
|
||||
|
|
@ -274,7 +339,7 @@ func (self *_runtime) cmpl_evaluate_nodeSequenceExpression(node *_nodeSequenceEx
|
|||
var result Value
|
||||
for _, node := range node.sequence {
|
||||
result = self.cmpl_evaluate_nodeExpression(node)
|
||||
result = self.GetValue(result)
|
||||
result = result.resolve()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
@ -284,31 +349,31 @@ func (self *_runtime) cmpl_evaluate_nodeUnaryExpression(node *_nodeUnaryExpressi
|
|||
target := self.cmpl_evaluate_nodeExpression(node.operand)
|
||||
switch node.operator {
|
||||
case token.TYPEOF, token.DELETE:
|
||||
if target._valueType == valueReference && target.reference().IsUnresolvable() {
|
||||
if target.kind == valueReference && target.reference().invalid() {
|
||||
if node.operator == token.TYPEOF {
|
||||
return toValue_string("undefined")
|
||||
}
|
||||
return TrueValue()
|
||||
return trueValue
|
||||
}
|
||||
}
|
||||
|
||||
switch node.operator {
|
||||
case token.NOT:
|
||||
targetValue := self.GetValue(target)
|
||||
if targetValue.toBoolean() {
|
||||
return FalseValue()
|
||||
targetValue := target.resolve()
|
||||
if targetValue.bool() {
|
||||
return falseValue
|
||||
}
|
||||
return TrueValue()
|
||||
return trueValue
|
||||
case token.BITWISE_NOT:
|
||||
targetValue := self.GetValue(target)
|
||||
targetValue := target.resolve()
|
||||
integerValue := toInt32(targetValue)
|
||||
return toValue_int32(^integerValue)
|
||||
case token.PLUS:
|
||||
targetValue := self.GetValue(target)
|
||||
return toValue_float64(targetValue.toFloat())
|
||||
targetValue := target.resolve()
|
||||
return toValue_float64(targetValue.float64())
|
||||
case token.MINUS:
|
||||
targetValue := self.GetValue(target)
|
||||
value := targetValue.toFloat()
|
||||
targetValue := target.resolve()
|
||||
value := targetValue.float64()
|
||||
// TODO Test this
|
||||
sign := float64(-1)
|
||||
if math.Signbit(value) {
|
||||
|
|
@ -316,45 +381,45 @@ func (self *_runtime) cmpl_evaluate_nodeUnaryExpression(node *_nodeUnaryExpressi
|
|||
}
|
||||
return toValue_float64(math.Copysign(value, sign))
|
||||
case token.INCREMENT:
|
||||
targetValue := self.GetValue(target)
|
||||
targetValue := target.resolve()
|
||||
if node.postfix {
|
||||
// Postfix++
|
||||
oldValue := targetValue.toFloat()
|
||||
oldValue := targetValue.float64()
|
||||
newValue := toValue_float64(+1 + oldValue)
|
||||
self.PutValue(target.reference(), newValue)
|
||||
self.putValue(target.reference(), newValue)
|
||||
return toValue_float64(oldValue)
|
||||
} else {
|
||||
// ++Prefix
|
||||
newValue := toValue_float64(+1 + targetValue.toFloat())
|
||||
self.PutValue(target.reference(), newValue)
|
||||
newValue := toValue_float64(+1 + targetValue.float64())
|
||||
self.putValue(target.reference(), newValue)
|
||||
return newValue
|
||||
}
|
||||
case token.DECREMENT:
|
||||
targetValue := self.GetValue(target)
|
||||
targetValue := target.resolve()
|
||||
if node.postfix {
|
||||
// Postfix--
|
||||
oldValue := targetValue.toFloat()
|
||||
oldValue := targetValue.float64()
|
||||
newValue := toValue_float64(-1 + oldValue)
|
||||
self.PutValue(target.reference(), newValue)
|
||||
self.putValue(target.reference(), newValue)
|
||||
return toValue_float64(oldValue)
|
||||
} else {
|
||||
// --Prefix
|
||||
newValue := toValue_float64(-1 + targetValue.toFloat())
|
||||
self.PutValue(target.reference(), newValue)
|
||||
newValue := toValue_float64(-1 + targetValue.float64())
|
||||
self.putValue(target.reference(), newValue)
|
||||
return newValue
|
||||
}
|
||||
case token.VOID:
|
||||
self.GetValue(target) // FIXME Side effect?
|
||||
return UndefinedValue()
|
||||
target.resolve() // FIXME Side effect?
|
||||
return Value{}
|
||||
case token.DELETE:
|
||||
reference := target.reference()
|
||||
if reference == nil {
|
||||
return TrueValue()
|
||||
return trueValue
|
||||
}
|
||||
return toValue_bool(target.reference().Delete())
|
||||
return toValue_bool(target.reference().delete())
|
||||
case token.TYPEOF:
|
||||
targetValue := self.GetValue(target)
|
||||
switch targetValue._valueType {
|
||||
targetValue := target.resolve()
|
||||
switch targetValue.kind {
|
||||
case valueUndefined:
|
||||
return toValue_string("undefined")
|
||||
case valueNull:
|
||||
|
|
@ -366,7 +431,7 @@ func (self *_runtime) cmpl_evaluate_nodeUnaryExpression(node *_nodeUnaryExpressi
|
|||
case valueString:
|
||||
return toValue_string("string")
|
||||
case valueObject:
|
||||
if targetValue._object().functionValue().call != nil {
|
||||
if targetValue._object().isCall() {
|
||||
return toValue_string("function")
|
||||
}
|
||||
return toValue_string("object")
|
||||
|
|
@ -381,11 +446,11 @@ func (self *_runtime) cmpl_evaluate_nodeUnaryExpression(node *_nodeUnaryExpressi
|
|||
func (self *_runtime) cmpl_evaluate_nodeVariableExpression(node *_nodeVariableExpression) Value {
|
||||
if node.initializer != nil {
|
||||
// FIXME If reference is nil
|
||||
left := getIdentifierReference(self.LexicalEnvironment(), node.name, false)
|
||||
left := getIdentifierReference(self, self.scope.lexical, node.name, false, _at(node.idx))
|
||||
right := self.cmpl_evaluate_nodeExpression(node.initializer)
|
||||
rightValue := self.GetValue(right)
|
||||
rightValue := right.resolve()
|
||||
|
||||
self.PutValue(left, rightValue)
|
||||
self.putValue(left, rightValue)
|
||||
}
|
||||
return toValue_string(node.name)
|
||||
}
|
||||
|
|
@ -12,10 +12,10 @@ func (self *_runtime) cmpl_evaluate_nodeStatement(node _nodeStatement) Value {
|
|||
// If the Interrupt channel is nil, then
|
||||
// we avoid runtime.Gosched() overhead (if any)
|
||||
// FIXME: Test this
|
||||
if self.Otto.Interrupt != nil {
|
||||
if self.otto.Interrupt != nil {
|
||||
runtime.Gosched()
|
||||
select {
|
||||
case value := <-self.Otto.Interrupt:
|
||||
case value := <-self.otto.Interrupt:
|
||||
value()
|
||||
default:
|
||||
}
|
||||
|
|
@ -24,8 +24,18 @@ func (self *_runtime) cmpl_evaluate_nodeStatement(node _nodeStatement) Value {
|
|||
switch node := node.(type) {
|
||||
|
||||
case *_nodeBlockStatement:
|
||||
// FIXME If result is break, then return the empty value?
|
||||
return self.cmpl_evaluate_nodeStatementList(node.list)
|
||||
labels := self.labels
|
||||
self.labels = nil
|
||||
|
||||
value := self.cmpl_evaluate_nodeStatementList(node.list)
|
||||
switch value.kind {
|
||||
case valueResult:
|
||||
switch value.evaluateBreak(labels) {
|
||||
case resultBreak:
|
||||
return emptyValue
|
||||
}
|
||||
}
|
||||
return value
|
||||
|
||||
case *_nodeBranchStatement:
|
||||
target := node.label
|
||||
|
|
@ -37,13 +47,13 @@ func (self *_runtime) cmpl_evaluate_nodeStatement(node _nodeStatement) Value {
|
|||
}
|
||||
|
||||
case *_nodeDebuggerStatement:
|
||||
return Value{} // Nothing happens.
|
||||
return emptyValue // Nothing happens.
|
||||
|
||||
case *_nodeDoWhileStatement:
|
||||
return self.cmpl_evaluate_nodeDoWhileStatement(node)
|
||||
|
||||
case *_nodeEmptyStatement:
|
||||
return Value{}
|
||||
return emptyValue
|
||||
|
||||
case *_nodeExpressionStatement:
|
||||
return self.cmpl_evaluate_nodeExpression(node.expression)
|
||||
|
|
@ -70,15 +80,15 @@ func (self *_runtime) cmpl_evaluate_nodeStatement(node _nodeStatement) Value {
|
|||
|
||||
case *_nodeReturnStatement:
|
||||
if node.argument != nil {
|
||||
return toValue(newReturnResult(self.GetValue(self.cmpl_evaluate_nodeExpression(node.argument))))
|
||||
return toValue(newReturnResult(self.cmpl_evaluate_nodeExpression(node.argument).resolve()))
|
||||
}
|
||||
return toValue(newReturnResult(UndefinedValue()))
|
||||
return toValue(newReturnResult(Value{}))
|
||||
|
||||
case *_nodeSwitchStatement:
|
||||
return self.cmpl_evaluate_nodeSwitchStatement(node)
|
||||
|
||||
case *_nodeThrowStatement:
|
||||
value := self.GetValue(self.cmpl_evaluate_nodeExpression(node.argument))
|
||||
value := self.cmpl_evaluate_nodeExpression(node.argument).resolve()
|
||||
panic(newException(value))
|
||||
|
||||
case *_nodeTryStatement:
|
||||
|
|
@ -89,7 +99,7 @@ func (self *_runtime) cmpl_evaluate_nodeStatement(node _nodeStatement) Value {
|
|||
for _, variable := range node.list {
|
||||
self.cmpl_evaluate_nodeVariableExpression(variable.(*_nodeVariableExpression))
|
||||
}
|
||||
return Value{}
|
||||
return emptyValue
|
||||
|
||||
case *_nodeWhileStatement:
|
||||
return self.cmpl_evaluate_nodeWhileStatement(node)
|
||||
|
|
@ -106,17 +116,17 @@ func (self *_runtime) cmpl_evaluate_nodeStatementList(list []_nodeStatement) Val
|
|||
var result Value
|
||||
for _, node := range list {
|
||||
value := self.cmpl_evaluate_nodeStatement(node)
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueResult:
|
||||
return value
|
||||
case valueEmpty:
|
||||
default:
|
||||
// We have GetValue here to (for example) trigger a
|
||||
// We have getValue here to (for example) trigger a
|
||||
// ReferenceError (of the not defined variety)
|
||||
// Not sure if this is the best way to error out early
|
||||
// for such errors or if there is a better way
|
||||
// TODO Do we still need this?
|
||||
result = self.GetValue(value)
|
||||
result = value.resolve()
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
|
@ -129,12 +139,12 @@ func (self *_runtime) cmpl_evaluate_nodeDoWhileStatement(node *_nodeDoWhileState
|
|||
|
||||
test := node.test
|
||||
|
||||
result := Value{}
|
||||
result := emptyValue
|
||||
resultBreak:
|
||||
for {
|
||||
for _, node := range node.body {
|
||||
value := self.cmpl_evaluate_nodeStatement(node)
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueResult:
|
||||
switch value.evaluateBreakContinue(labels) {
|
||||
case resultReturn:
|
||||
|
|
@ -150,7 +160,7 @@ resultBreak:
|
|||
}
|
||||
}
|
||||
resultContinue:
|
||||
if !self.GetValue(self.cmpl_evaluate_nodeExpression(test)).isTrue() {
|
||||
if !self.cmpl_evaluate_nodeExpression(test).resolve().bool() {
|
||||
// Stahp: do ... while (false)
|
||||
break
|
||||
}
|
||||
|
|
@ -164,11 +174,11 @@ func (self *_runtime) cmpl_evaluate_nodeForInStatement(node *_nodeForInStatement
|
|||
self.labels = nil
|
||||
|
||||
source := self.cmpl_evaluate_nodeExpression(node.source)
|
||||
sourceValue := self.GetValue(source)
|
||||
sourceValue := source.resolve()
|
||||
|
||||
switch sourceValue._valueType {
|
||||
switch sourceValue.kind {
|
||||
case valueUndefined, valueNull:
|
||||
return emptyValue()
|
||||
return emptyValue
|
||||
}
|
||||
|
||||
sourceObject := self.toObject(sourceValue)
|
||||
|
|
@ -176,22 +186,22 @@ func (self *_runtime) cmpl_evaluate_nodeForInStatement(node *_nodeForInStatement
|
|||
into := node.into
|
||||
body := node.body
|
||||
|
||||
result := Value{}
|
||||
result := emptyValue
|
||||
object := sourceObject
|
||||
for object != nil {
|
||||
enumerateValue := Value{}
|
||||
enumerateValue := emptyValue
|
||||
object.enumerate(false, func(name string) bool {
|
||||
into := self.cmpl_evaluate_nodeExpression(into)
|
||||
// In the case of: for (var abc in def) ...
|
||||
if into.reference() == nil {
|
||||
identifier := toString(into)
|
||||
identifier := into.string()
|
||||
// TODO Should be true or false (strictness) depending on context
|
||||
into = toValue(getIdentifierReference(self.LexicalEnvironment(), identifier, false))
|
||||
into = toValue(getIdentifierReference(self, self.scope.lexical, identifier, false, -1))
|
||||
}
|
||||
self.PutValue(into.reference(), toValue_string(name))
|
||||
self.putValue(into.reference(), toValue_string(name))
|
||||
for _, node := range body {
|
||||
value := self.cmpl_evaluate_nodeStatement(node)
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueResult:
|
||||
switch value.evaluateBreakContinue(labels) {
|
||||
case resultReturn:
|
||||
|
|
@ -233,22 +243,22 @@ func (self *_runtime) cmpl_evaluate_nodeForStatement(node *_nodeForStatement) Va
|
|||
|
||||
if initializer != nil {
|
||||
initialResult := self.cmpl_evaluate_nodeExpression(initializer)
|
||||
self.GetValue(initialResult) // Side-effect trigger
|
||||
initialResult.resolve() // Side-effect trigger
|
||||
}
|
||||
|
||||
result := Value{}
|
||||
result := emptyValue
|
||||
resultBreak:
|
||||
for {
|
||||
if test != nil {
|
||||
testResult := self.cmpl_evaluate_nodeExpression(test)
|
||||
testResultValue := self.GetValue(testResult)
|
||||
if toBoolean(testResultValue) == false {
|
||||
testResultValue := testResult.resolve()
|
||||
if testResultValue.bool() == false {
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, node := range body {
|
||||
value := self.cmpl_evaluate_nodeStatement(node)
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueResult:
|
||||
switch value.evaluateBreakContinue(labels) {
|
||||
case resultReturn:
|
||||
|
|
@ -266,7 +276,7 @@ resultBreak:
|
|||
resultContinue:
|
||||
if update != nil {
|
||||
updateResult := self.cmpl_evaluate_nodeExpression(update)
|
||||
self.GetValue(updateResult) // Side-effect trigger
|
||||
updateResult.resolve() // Side-effect trigger
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
|
@ -274,14 +284,14 @@ resultBreak:
|
|||
|
||||
func (self *_runtime) cmpl_evaluate_nodeIfStatement(node *_nodeIfStatement) Value {
|
||||
test := self.cmpl_evaluate_nodeExpression(node.test)
|
||||
testValue := self.GetValue(test)
|
||||
if toBoolean(testValue) {
|
||||
testValue := test.resolve()
|
||||
if testValue.bool() {
|
||||
return self.cmpl_evaluate_nodeStatement(node.consequent)
|
||||
} else if node.alternate != nil {
|
||||
return self.cmpl_evaluate_nodeStatement(node.alternate)
|
||||
}
|
||||
|
||||
return Value{}
|
||||
return emptyValue
|
||||
}
|
||||
|
||||
func (self *_runtime) cmpl_evaluate_nodeSwitchStatement(node *_nodeSwitchStatement) Value {
|
||||
|
|
@ -302,18 +312,18 @@ func (self *_runtime) cmpl_evaluate_nodeSwitchStatement(node *_nodeSwitchStateme
|
|||
}
|
||||
}
|
||||
|
||||
result := Value{}
|
||||
result := emptyValue
|
||||
if target != -1 {
|
||||
for _, clause := range node.body[target:] {
|
||||
for _, statement := range clause.consequent {
|
||||
value := self.cmpl_evaluate_nodeStatement(statement)
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueResult:
|
||||
switch value.evaluateBreak(labels) {
|
||||
case resultReturn:
|
||||
return value
|
||||
case resultBreak:
|
||||
return Value{}
|
||||
return emptyValue
|
||||
}
|
||||
case valueEmpty:
|
||||
default:
|
||||
|
|
@ -332,14 +342,15 @@ func (self *_runtime) cmpl_evaluate_nodeTryStatement(node *_nodeTryStatement) Va
|
|||
})
|
||||
|
||||
if exception && node.catch != nil {
|
||||
|
||||
lexicalEnvironment := self._executionContext(0).newDeclarativeEnvironment(self)
|
||||
outer := self.scope.lexical
|
||||
self.scope.lexical = self.newDeclarationStash(outer)
|
||||
defer func() {
|
||||
self._executionContext(0).LexicalEnvironment = lexicalEnvironment
|
||||
self.scope.lexical = outer
|
||||
}()
|
||||
// TODO If necessary, convert TypeError<runtime> => TypeError
|
||||
// That, is, such errors can be thrown despite not being JavaScript "native"
|
||||
self.localSet(node.catch.parameter, tryCatchValue)
|
||||
// strict = false
|
||||
self.scope.lexical.setValue(node.catch.parameter, tryCatchValue, false)
|
||||
|
||||
// FIXME node.CatchParameter
|
||||
// FIXME node.Catch
|
||||
|
|
@ -350,7 +361,7 @@ func (self *_runtime) cmpl_evaluate_nodeTryStatement(node *_nodeTryStatement) Va
|
|||
|
||||
if node.finally != nil {
|
||||
finallyValue := self.cmpl_evaluate_nodeStatement(node.finally)
|
||||
if finallyValue.isResult() {
|
||||
if finallyValue.kind == valueResult {
|
||||
return finallyValue
|
||||
}
|
||||
}
|
||||
|
|
@ -369,16 +380,16 @@ func (self *_runtime) cmpl_evaluate_nodeWhileStatement(node *_nodeWhileStatement
|
|||
labels := append(self.labels, "")
|
||||
self.labels = nil
|
||||
|
||||
result := Value{}
|
||||
result := emptyValue
|
||||
resultBreakContinue:
|
||||
for {
|
||||
if !self.GetValue(self.cmpl_evaluate_nodeExpression(test)).isTrue() {
|
||||
if !self.cmpl_evaluate_nodeExpression(test).resolve().bool() {
|
||||
// Stahp: while (false) ...
|
||||
break
|
||||
}
|
||||
for _, node := range body {
|
||||
value := self.cmpl_evaluate_nodeStatement(node)
|
||||
switch value._valueType {
|
||||
switch value.kind {
|
||||
case valueResult:
|
||||
switch value.evaluateBreakContinue(labels) {
|
||||
case resultReturn:
|
||||
|
|
@ -399,11 +410,11 @@ resultBreakContinue:
|
|||
|
||||
func (self *_runtime) cmpl_evaluate_nodeWithStatement(node *_nodeWithStatement) Value {
|
||||
object := self.cmpl_evaluate_nodeExpression(node.object)
|
||||
objectValue := self.GetValue(object)
|
||||
previousLexicalEnvironment, lexicalEnvironment := self._executionContext(0).newLexicalEnvironment(self.toObject(objectValue))
|
||||
lexicalEnvironment.ProvideThis = true
|
||||
outer := self.scope.lexical
|
||||
lexical := self.newObjectStash(self.toObject(object.resolve()), outer)
|
||||
self.scope.lexical = lexical
|
||||
defer func() {
|
||||
self._executionContext(0).LexicalEnvironment = previousLexicalEnvironment
|
||||
self.scope.lexical = outer
|
||||
}()
|
||||
|
||||
return self.cmpl_evaluate_nodeStatement(node.body)
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue