diff --git a/vendor/github.com/go-gl-legacy/gl/AUTHORS b/vendor/github.com/go-gl-legacy/gl/AUTHORS new file mode 100644 index 0000000..2dda705 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/AUTHORS @@ -0,0 +1,41 @@ +# This is the official list of go-gl/gl authors for copyright purposes. + +# Seed: $ git shortlog -e | egrep '^\S+' | sed -E 's|(.*<.*>).*|\1|g' + +# Please keep the list sorted. + +# Name (optional github handle) + +Arne Doering +Chris Jones +Christoph Schunk +David Aguilar (davvid) +DeedleFake +Dennis Honeyman +Emil Arfvidsson +Fabian Wickborn +Henry Finucane +Jacob Parker +Jannis +Jim Arnold (jimarnold) +Jim Teeuwen (jteeuwen) +Josh Smith +Jragonmiris +Kirill A. Shutemov (kiryl) +Laurie Clark-Michalek +Lawrence E. Bakst (tildeleb) +Matt Kovars +Miroslav Puda (pakanek) +Niriel +Noel Cower (nilium) +Peter Waller (pwaller) +Piotr Praszmo (banthar) +PolyFloyd (PolyFloyd) +Przemyslaw Szczepaniak +Tom Myers +Vova +Yohann R. Coppel +pkkp +rhencke +shogg +tbruyelle diff --git a/vendor/github.com/go-gl-legacy/gl/LICENSE b/vendor/github.com/go-gl-legacy/gl/LICENSE new file mode 100644 index 0000000..23e6ea8 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2012 The go-gl Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of go-gl nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/go-gl-legacy/gl/README.md b/vendor/github.com/go-gl-legacy/gl/README.md new file mode 100644 index 0000000..648e95b --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/README.md @@ -0,0 +1,105 @@ +gl | OpenGL Bindings for golang +=============================== + +You will need [GLEW](http://glew.sourceforge.net/) at least version 1.5.4. + +Once GLEW is installed, you can install this package with `go get`: + + go get github.com/go-gl-legacy/gl + +Contact / discussion mailing list +--------------------------------- + +The discussion is hosted on [google groups](https://groups.google.com/forum/#!forum/go-gl). +We can also be found periodically on IRC, [#go-gl on freenode](http://webchat.freenode.net/?randomnick=1&channels=go-gl&prompt=1). + +Documentation and examples +-------------------------- + +Autogenerated documentation can be found on +[godoc.org](http://godoc.org/github.com/go-gl-legacy/gl), and the more thorough +[official GL SDK documentation](http://www.opengl.org/sdk/docs/man/xhtml/) applies. + +Examples can be found in our [examples repository](https://github.com/go-gl/examples). + +# More libraries: Easy windowing, meshes, text rendering, etc: + +* [GLFW bindings](https://github.com/go-gl/glfw) for easy windowing, input etc. +* [gltext](https://github.com/go-gl/gltext) a native go library for glyph packing and text rendering +* [glu](https://github.com/go-gl/glu) GLU bindings +* [glchart](https://github.com/go-gl/glchart) a [go chart](https://github.com/vdobler/chart) OpenGL backend +* [gldebug](https://github.com/go-gl/gldebug) graphical timing and memory debugging utilities + +# Problems and contributing + +If you encounter any problems please [file an issue](https://github.com/go-gl-legacy/gl/issues/new). +Pull requests are welcome. We're looking for contributors! + +# Setting your GOPATH + +For the above `go get` to work without without requiring admin privileges, +please refer to [go documentation](http://golang.org/doc/code.html) or this +[five minute go screencast](http://www.youtube.com/watch?v=XCsL89YtqCs). + +Operating System Specific advice +-------------------------------- + +The `go-gl/gl` authors primarily develop on Linux-based machines. The package +should work on other operating systems, if you encounter problems after following +the instructions below, please file an issue. + +## Linux / OSX + +This package uses [cgo](http://golang.org/cmd/cgo/) and therefore you will need +a C compiler such as GCC. On Debian, you can install `build-essential` to get this. + +You need to install the GLEW development libraries the appropriate package manager +for your Linux distribution or by downloading the sources from the +[GLEW website](http://glew.sourceforge.net/). + +For non-standard GLEW install locations, after `go get` cd to +`$GOPATH/src/github.com/go-gl-legacy/gl` and run: + + CGO_CFLAGS="-I/path/to/includes" CGO_LDFLAGS="-L/path/to/libs" go install + +You may be able to determine the appropriate flags using: + + pkg-config glew --libs --cflags + +Note that we import from `GL/glew.h`, so if `pkg-config --cflags` reports +`/opt/include/GL`, you may need to remove `/GL` so that `CGO_CFLAGS=-I/opt/include`. + +## OSX + +The following instructions are currently a best guess. If you develop on OSX +please [get in contact](http://go-gl.github.com) and let us know if this works, +or [not](https://github.com/go-gl-legacy/gl/issues/new)! + +### GLEW from Homebrew / Macports + +These can be used to install GLEW. Beware that you may need to set `CGO_CFLAGS` +and `CGO_LDFLAGS` - the Linux instructions above are relevant. + +## Windows + +Windows support is currently unknown. `gl` uses `cgo`, and therefore you will +need a C compiler. If you install the GLEW to your compiler's include and lib +directories, things should work. If they do not, please +[contact us](http://go-gl.github.com). + +OpenGL 4.* +---------- + +The `glew-1.10` branch is available for those that need newer OpenGL 4.* functionality. +To use it, manually clone the repository and checkout the branch. +As the branchname implies, it's using GLEW 1.10. + +Forward compatibility +--------------------- + +It is the intent of the `go-gl` authors to keep `gl` and related packages +forward-compatible at both the API/ABI levels _per go release_ so that you can +continue to import from this github repository. Development requiring breakage +will occur on the `glew-1.10` branch, and will be merged with master when a new go +version is released. + diff --git a/vendor/github.com/go-gl-legacy/gl/attriblocation.go b/vendor/github.com/go-gl-legacy/gl/attriblocation.go new file mode 100644 index 0000000..a9301d9 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/attriblocation.go @@ -0,0 +1,61 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" + +// AttribLocation + +type AttribLocation int + +func (indx AttribLocation) Attrib1f(x float32) { + C.glVertexAttrib1f(C.GLuint(indx), C.GLfloat(x)) +} + +func (indx AttribLocation) Attrib1fv(values *[1]float32) { + C.glVertexAttrib1fv(C.GLuint(indx), (*C.GLfloat)(&values[0])) +} + +func (indx AttribLocation) Attrib2f(x float32, y float32) { + C.glVertexAttrib2f(C.GLuint(indx), C.GLfloat(x), C.GLfloat(y)) +} + +func (indx AttribLocation) Attrib2fv(values *[2]float32) { + C.glVertexAttrib2fv(C.GLuint(indx), (*C.GLfloat)(&values[0])) +} + +func (indx AttribLocation) Attrib3f(x float32, y float32, z float32) { + C.glVertexAttrib3f(C.GLuint(indx), C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) +} + +func (indx AttribLocation) Attrib3fv(values *[3]float32) { + C.glVertexAttrib3fv(C.GLuint(indx), (*C.GLfloat)(&values[0])) +} + +func (indx AttribLocation) Attrib4f(x float32, y float32, z float32, w float32) { + C.glVertexAttrib4f(C.GLuint(indx), C.GLfloat(x), C.GLfloat(y), C.GLfloat(z), C.GLfloat(w)) +} + +func (indx AttribLocation) Attrib4fv(values *[4]float32) { + C.glVertexAttrib4fv(C.GLuint(indx), (*C.GLfloat)(&values[0])) +} + +func (indx AttribLocation) AttribPointer(size uint, typ GLenum, normalized bool, stride int, pointer interface{}) { + C.glVertexAttribPointer(C.GLuint(indx), C.GLint(size), C.GLenum(typ), + glBool(normalized), C.GLsizei(stride), ptr(pointer)) +} + +func (indx AttribLocation) EnableArray() { + C.glEnableVertexAttribArray(C.GLuint(indx)) +} + +func (indx AttribLocation) DisableArray() { + C.glDisableVertexAttribArray(C.GLuint(indx)) +} + +func (indx AttribLocation) AttribDivisor(divisor int) { + C.glVertexAttribDivisor(C.GLuint(indx), C.GLuint(divisor)) +} diff --git a/vendor/github.com/go-gl-legacy/gl/buffer.go b/vendor/github.com/go-gl-legacy/gl/buffer.go new file mode 100644 index 0000000..b9cffde --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/buffer.go @@ -0,0 +1,126 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" +import "unsafe" +import "reflect" + +// Buffer Objects + +type Buffer Object + +// Create single buffer object +func GenBuffer() Buffer { + var b C.GLuint + C.glGenBuffers(1, &b) + return Buffer(b) +} + +// Fill slice with new buffers +func GenBuffers(buffers []Buffer) { + if len(buffers) > 0 { + C.glGenBuffers(C.GLsizei(len(buffers)), (*C.GLuint)(&buffers[0])) + } +} + +// Delete buffer object +func (buffer Buffer) Delete() { + b := C.GLuint(buffer) + C.glDeleteBuffers(1, &b) +} + +// Delete all buffers in slice +func DeleteBuffers(buffers []Buffer) { + if len(buffers) > 0 { + C.glDeleteBuffers(C.GLsizei(len(buffers)), (*C.GLuint)(&buffers[0])) + } +} + +// Bind this buffer as target +func (buffer Buffer) Bind(target GLenum) { + C.glBindBuffer(C.GLenum(target), C.GLuint(buffer)) +} + +// Remove buffer binding +func (buffer Buffer) Unbind(target GLenum) { + C.glBindBuffer(C.GLenum(target), C.GLuint(0)) +} + +// Bind this buffer as index of target +func (buffer Buffer) BindBufferBase(target GLenum, index uint) { + C.glBindBufferBase(C.GLenum(target), C.GLuint(index), C.GLuint(buffer)) +} + +// Bind this buffer range as index of target +func (buffer Buffer) BindBufferRange(target GLenum, index uint, offset int, size uint) { + C.glBindBufferRange(C.GLenum(target), C.GLuint(index), C.GLuint(buffer), C.GLintptr(offset), C.GLsizeiptr(size)) +} + +// Creates and initializes a buffer object's data store +func BufferData(target GLenum, size int, data interface{}, usage GLenum) { + C.glBufferData(C.GLenum(target), C.GLsizeiptr(size), ptr(data), C.GLenum(usage)) +} + +// Update a subset of a buffer object's data store +func BufferSubData(target GLenum, offset int, size int, data interface{}) { + C.glBufferSubData(C.GLenum(target), C.GLintptr(offset), C.GLsizeiptr(size), + ptr(data)) +} + +// Returns a subset of a buffer object's data store +func GetBufferSubData(target GLenum, offset int, size int, data interface{}) { + C.glGetBufferSubData(C.GLenum(target), C.GLintptr(offset), + C.GLsizeiptr(size), ptr(data)) +} + +// Map a buffer object's data store +func MapBuffer(target GLenum, access GLenum) unsafe.Pointer { + return unsafe.Pointer(C.glMapBuffer(C.GLenum(target), C.GLenum(access))) +} + +// Maps the buffer with MapBuffer() and returns a pointer to the slice pointing +// to the mapped buffer. See also the MapBuffer convenience functions. +// WARNING: This function makes use of reflect.SliceHeader which may reduce +// portability of your application. See the reflect.SliceHeader documentation +// for more information. +func MapBufferSlice(target GLenum, access GLenum, bytesPerElement int) unsafe.Pointer { + rawLength := int(GetBufferParameteriv(target, BUFFER_SIZE)) + return unsafe.Pointer(&reflect.SliceHeader{ + Data: uintptr(MapBuffer(target, access)), + Len: rawLength / bytesPerElement, + Cap: rawLength / bytesPerElement, + }) +} + +// Map a buffer object's data store and return it as a slice +func MapBufferFloat32(target GLenum, access GLenum) []float32 { + return *(*[]float32)(MapBufferSlice(target, access, 4)) +} + +// Map a buffer object's data store and return it as a slice +func MapBufferUint32(target GLenum, access GLenum) []uint32 { + return *(*[]uint32)(MapBufferSlice(target, access, 4)) +} + +// Unmap a buffer object's data store +func UnmapBuffer(target GLenum) bool { + return goBool(C.glUnmapBuffer(C.GLenum(target))) +} + +// Return buffer pointer +func GetBufferPointerv(target GLenum, pname GLenum) unsafe.Pointer { + var ptr unsafe.Pointer + C.glGetBufferPointerv(C.GLenum(target), C.GLenum(pname), &ptr) + return ptr +} + +// Return parameters of a buffer object +func GetBufferParameteriv(target GLenum, pname GLenum) int32 { + var param C.GLint + C.glGetBufferParameteriv(C.GLenum(target), C.GLenum(pname), ¶m) + return int32(param) +} diff --git a/vendor/github.com/go-gl-legacy/gl/color.go b/vendor/github.com/go-gl-legacy/gl/color.go new file mode 100644 index 0000000..76aac2b --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/color.go @@ -0,0 +1,184 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" + +//void glColor3b (int8 red, int8 green, int8 blue) +func Color3b(red int8, green int8, blue int8) { + C.glColor3b(C.GLbyte(red), C.GLbyte(green), C.GLbyte(blue)) +} + +//void glColor3bv (const int8 *v) +func Color3bv(v *[3]int8) { + C.glColor3bv((*C.GLbyte)(&v[0])) +} + +//void glColor3d (float64 red, float64 green, float64 blue) +func Color3d(red float64, green float64, blue float64) { + C.glColor3d(C.GLdouble(red), C.GLdouble(green), C.GLdouble(blue)) +} + +//void glColor3dv (const float64 *v) +func Color3dv(v *[3]float64) { + C.glColor3dv((*C.GLdouble)(&v[0])) +} + +//void glColor3f (float32 red, float32 green, float32 blue) +func Color3f(red float32, green float32, blue float32) { + C.glColor3f(C.GLfloat(red), C.GLfloat(green), C.GLfloat(blue)) +} + +//void glColor3fv (const float *v) +func Color3fv(v *[3]float32) { + C.glColor3fv((*C.GLfloat)(&v[0])) +} + +//void glColor3i (int red, int green, int blue) +func Color3i(red int, green int, blue int) { + C.glColor3i(C.GLint(red), C.GLint(green), C.GLint(blue)) +} + +//void glColor3iv (const int *v) +func Color3iv(v *[3]int32) { + C.glColor3iv((*C.GLint)(&v[0])) +} + +//void glColor3s (int16 red, int16 green, int16 blue) +func Color3s(red int16, green int16, blue int16) { + C.glColor3s(C.GLshort(red), C.GLshort(green), C.GLshort(blue)) +} + +//void glColor3sv (const int16 *v) +func Color3sv(v *[3]int16) { + C.glColor3sv((*C.GLshort)(&v[0])) +} + +//void glColor3ub (uint8 red, uint8 green, uint8 blue) +func Color3ub(red uint8, green uint8, blue uint8) { + C.glColor3ub(C.GLubyte(red), C.GLubyte(green), C.GLubyte(blue)) +} + +//void glColor3ubv (const uint8 *v) +func Color3ubv(v *[3]uint8) { + C.glColor3ubv((*C.GLubyte)(&v[0])) +} + +//void glColor3ui (uint red, uint green, uint blue) +func Color3ui(red uint, green uint, blue uint) { + C.glColor3ui(C.GLuint(red), C.GLuint(green), C.GLuint(blue)) +} + +//void glColor3uiv (const uint *v) +func Color3uiv(v *[3]uint32) { + C.glColor3uiv((*C.GLuint)(&v[0])) +} + +//void glColor3us (uint16 red, uint16 green, uint16 blue) +func Color3us(red uint16, green uint16, blue uint16) { + C.glColor3us(C.GLushort(red), C.GLushort(green), C.GLushort(blue)) +} + +//void glColor3usv (const uint16 *v) +func Color3usv(v *[3]uint16) { + C.glColor3usv((*C.GLushort)(&v[0])) +} + +//void glColor4b (int8 red, int8 green, int8 blue, int8 alpha) +func Color4b(red int8, green int8, blue int8, alpha int8) { + C.glColor4b(C.GLbyte(red), C.GLbyte(green), C.GLbyte(blue), C.GLbyte(alpha)) +} + +//void glColor4bv (const int8 *v) +func Color4bv(v *[4]int8) { + C.glColor4bv((*C.GLbyte)(&v[0])) +} + +//void glColor4d (float64 red, float64 green, float64 blue, float64 alpha) +func Color4d(red float64, green float64, blue float64, alpha float64) { + C.glColor4d(C.GLdouble(red), C.GLdouble(green), C.GLdouble(blue), C.GLdouble(alpha)) +} + +//void glColor4dv (const float64 *v) +func Color4dv(v *[4]float64) { + C.glColor4dv((*C.GLdouble)(&v[0])) +} + +//void glColor4f (float32 red, float32 green, float32 blue, float32 alpha) +func Color4f(red float32, green float32, blue float32, alpha float32) { + C.glColor4f(C.GLfloat(red), C.GLfloat(green), C.GLfloat(blue), C.GLfloat(alpha)) +} + +//void glColor4fv (const float *v) +func Color4fv(v *[4]float32) { + C.glColor4fv((*C.GLfloat)(&v[0])) +} + +//void glColor4i (int red, int green, int blue, int alpha) +func Color4i(red int, green int, blue int, alpha int) { + C.glColor4i(C.GLint(red), C.GLint(green), C.GLint(blue), C.GLint(alpha)) +} + +//void glColor4iv (const int *v) +func Color4iv(v *[4]int32) { + C.glColor4iv((*C.GLint)(&v[0])) +} + +//void glColor4s (int16 red, int16 green, int16 blue, int16 alpha) +func Color4s(red int16, green int16, blue int16, alpha int16) { + C.glColor4s(C.GLshort(red), C.GLshort(green), C.GLshort(blue), C.GLshort(alpha)) +} + +//void glColor4sv (const int16 *v) +func Color4sv(v *[4]int16) { + C.glColor4sv((*C.GLshort)(&v[0])) +} + +//void glColor4ub (uint8 red, uint8 green, uint8 blue, uint8 alpha) +func Color4ub(red uint8, green uint8, blue uint8, alpha uint8) { + C.glColor4ub(C.GLubyte(red), C.GLubyte(green), C.GLubyte(blue), C.GLubyte(alpha)) +} + +//void glColor4ubv (const uint8 *v) +func Color4ubv(v *[4]uint8) { + C.glColor4ubv((*C.GLubyte)(&v[0])) +} + +//void glColor4ui (uint red, uint green, uint blue, uint alpha) +func Color4ui(red uint, green uint, blue uint, alpha uint) { + C.glColor4ui(C.GLuint(red), C.GLuint(green), C.GLuint(blue), C.GLuint(alpha)) +} + +//void glColor4uiv (const uint *v) +func Color4uiv(v *[4]uint32) { + C.glColor4uiv((*C.GLuint)(&v[0])) +} + +//void glColor4us (uint16 red, uint16 green, uint16 blue, uint16 alpha) +func Color4us(red uint16, green uint16, blue uint16, alpha uint16) { + C.glColor4us(C.GLushort(red), C.GLushort(green), C.GLushort(blue), C.GLushort(alpha)) +} + +//void glColor4usv (const uint16 *v) +func Color4usv(v *[4]uint16) { + C.glColor4usv((*C.GLushort)(&v[0])) +} + +//void glColorMask (bool red, bool green, bool blue, bool alpha) +func ColorMask(red bool, green bool, blue bool, alpha bool) { + C.glColorMask(glBool(red), glBool(green), glBool(blue), glBool(alpha)) +} + +//void glColorMaterial (GLenum face, GLenum mode) +func ColorMaterial(face GLenum, mode GLenum) { + C.glColorMaterial(C.GLenum(face), C.GLenum(mode)) +} + +//void glColorPointer (int size, GLenum type, int stride, const GLvoid *pointer) +func ColorPointer(size int, typ GLenum, stride int, pointer interface{}) { + C.glColorPointer(C.GLint(size), C.GLenum(typ), C.GLsizei(stride), + ptr(pointer)) +} diff --git a/vendor/github.com/go-gl-legacy/gl/debugoutput.go b/vendor/github.com/go-gl-legacy/gl/debugoutput.go new file mode 100644 index 0000000..122f22b --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/debugoutput.go @@ -0,0 +1,93 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +import "unsafe" + +// #include "gl.h" +// +// void goDebugCB(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, char *message); +// +// static inline void debugProcCB(GLenum source, +// GLenum type, +// GLuint id, +// GLenum severity, +// GLsizei length, +// const GLchar* message, +// void* userParam) +// { +// goDebugCB(source, type, id, severity, length, (char *)message); +// } +// +// static inline void glDebugMessageCB(void) +// { +// glDebugMessageCallbackARB(debugProcCB, NULL); +// } +// +// /* +// * Depending on glew version 'message' could be 'GLchar*' or 'char*' which +// * causes problems in more strict Go type system. Let's work it around in C +// */ +// static inline void __glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, +// GLsizei length, const char *message) +// { +// glDebugMessageInsertARB(source, type, id, severity, length, message); +// } +// +// static inline void GetDebugMessageLog(GLuint count, GLsizei bufSize, GLenum *sources, +// GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, char *messageLog) +// { +// glGetDebugMessageLogARB(count, bufSize, sources, types, ids, severities, lengths, messageLog); +// } +import "C" + +type debugProc func(source GLenum, typ GLenum, id uint, severity GLenum, message string) + +var debugCB debugProc + +//export goDebugCB +func goDebugCB(source GLenum, typ GLenum, id GLuint, severity GLenum, length GLsizei, message *C.char) { + debugCB(source, typ, uint(id), severity, C.GoStringN(message, C.int(length))) +} + +func DebugMessageCallback(cbfunc debugProc) { + if cbfunc == nil { + C.glDebugMessageCallbackARB(nil, nil) + } else { + debugCB = cbfunc + C.glDebugMessageCB() + } +} + +func DebugMessageControl(source GLenum, typ GLenum, severity GLenum, ids []uint, enabled bool) { + C.glDebugMessageControlARB(C.GLenum(source), C.GLenum(typ), C.GLenum(severity), + C.GLsizei(len(ids)), (*C.GLuint)(unsafe.Pointer(&ids)), glBool(enabled)) +} + +func DebugMessageInsert(source GLenum, typ GLenum, id uint, severity GLenum, message string) { + C.__glDebugMessageInsert(C.GLenum(source), C.GLenum(typ), C.GLuint(id), C.GLenum(severity), + C.GLsizei(len(message)), C.CString(message)) +} + +func GetNextDebugMessage() (msg string, source GLenum, typ GLenum, id uint, severity GLenum) { + length := []int32{0} + GetIntegerv(DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, length) + if length[0] < 1 { + msg = "" + return + } + + buf := C.malloc(C.size_t(length[0])) + defer C.free(buf) + + _id := []GLuint{0} + C.GetDebugMessageLog(C.GLuint(1), C.GLsizei(length[0]), + (*C.GLenum)(&source), (*C.GLenum)(&typ), (*C.GLuint)(&_id[0]), + (*C.GLenum)(&severity), nil, (*C.char)(buf)) + + id = uint(_id[0]) + msg = C.GoString((*C.char)(buf)) + return +} diff --git a/vendor/github.com/go-gl-legacy/gl/framebuffer.go b/vendor/github.com/go-gl-legacy/gl/framebuffer.go new file mode 100644 index 0000000..8439854 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/framebuffer.go @@ -0,0 +1,94 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" + +// Framebuffer Objects +// TODO: implement GLsync stuff +type Framebuffer Object + +// void glBindFramebuffer(GLenum target, GLuint framebuffer); +// +// Binds fb to target FRAMEBUFFER. To bind to a specific target, see BindTarget. +func (fb Framebuffer) Bind() { + C.glBindFramebuffer(C.GLenum(FRAMEBUFFER), C.GLuint(fb)) +} + +// Binds fb to the specified target. +// +// See issue at github for why this function exists: +// http://github.com/go-gl/gl/issues/113 +func (fb Framebuffer) BindTarget(target GLenum) { + C.glBindFramebuffer(C.GLenum(target), C.GLuint(fb)) +} + +// Unbinds target FRAMEBUFFER. To unbind a a specific target, see UnbindTarget. +func (fb Framebuffer) Unbind() { + C.glBindFramebuffer(C.GLenum(FRAMEBUFFER), 0) +} + +// Unbinds the specified target. +// +// See issue at github for why this function exists: +// http://github.com/go-gl/gl/issues/113 +func (fb Framebuffer) UnbindTarget(target GLenum) { + C.glBindFramebuffer(C.GLenum(target), 0) +} + +// void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +func BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1 int, mask GLbitfield, filter GLenum) { + C.glBlitFramebuffer(C.GLint(srcX0), C.GLint(srcY0), C.GLint(srcX1), C.GLint(srcY1), C.GLint(dstX0), C.GLint(dstY0), C.GLint(dstX1), C.GLint(dstY1), C.GLbitfield(mask), C.GLenum(filter)) +} + +// GLenum glCheckFramebufferStatus(GLenum target); +func CheckFramebufferStatus(target GLenum) GLenum { + return (GLenum)(C.glCheckFramebufferStatus(C.GLenum(target))) +} + +// void glDeleteFramebuffers(GLsizei n, GLuint* framebuffers); +func (fb Framebuffer) Delete() { + C.glDeleteFramebuffers(1, (*C.GLuint)(&fb)) +} + +func DeleteFramebuffers(bufs []Framebuffer) { + if len(bufs) > 0 { + C.glDeleteFramebuffers(C.GLsizei(len(bufs)), (*C.GLuint)(&bufs[0])) + } +} + +// void glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +func FramebufferTexture1D(target, attachment, textarget GLenum, texture Texture, level int) { + C.glFramebufferTexture1D(C.GLenum(target), C.GLenum(attachment), C.GLenum(textarget), C.GLuint(texture), C.GLint(level)) +} + +// void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +func FramebufferTexture2D(target, attachment, textarget GLenum, texture Texture, level int) { + C.glFramebufferTexture2D(C.GLenum(target), C.GLenum(attachment), C.GLenum(textarget), C.GLuint(texture), C.GLint(level)) +} + +// void glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); +func FramebufferTexture3D(target, attachment, textarget GLenum, texture Texture, level int, layer int) { + C.glFramebufferTexture3D(C.GLenum(target), C.GLenum(attachment), C.GLenum(textarget), C.GLuint(texture), C.GLint(level), C.GLint(layer)) +} + +// void glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +func FramebufferTextureLayer(target, attachment GLenum, texture Texture, level, layer int) { + C.glFramebufferTextureLayer(C.GLenum(target), C.GLenum(attachment), C.GLuint(texture), C.GLint(level), C.GLint(layer)) +} + +// void glGenFramebuffers(GLsizei n, GLuint* ids); +func GenFramebuffer() Framebuffer { + var b C.GLuint + C.glGenFramebuffers(1, &b) + return Framebuffer(b) +} + +func GenFramebuffers(bufs []Framebuffer) { + if len(bufs) > 0 { + C.glGenFramebuffers(C.GLsizei(len(bufs)), (*C.GLuint)(&bufs[0])) + } +} diff --git a/vendor/github.com/go-gl-legacy/gl/gl.go b/vendor/github.com/go-gl-legacy/gl/gl.go new file mode 100644 index 0000000..82f237c --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/gl.go @@ -0,0 +1,1233 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #cgo darwin LDFLAGS: -framework OpenGL -lGLEW +// #cgo windows LDFLAGS: -lglew32 -lopengl32 +// #cgo linux LDFLAGS: -lGLEW -lGL +// #cgo freebsd CFLAGS: -I/usr/local/include +// #cgo freebsd LDFLAGS: -L/usr/local/lib -lglfw +// #include "gl.h" +// void SetGlewExperimental(GLboolean v) { glewExperimental = v; } +import "C" +import "unsafe" +import "reflect" + +type GLenum C.GLenum +type GLbitfield C.GLbitfield +type GLclampf C.GLclampf +type GLclampd C.GLclampd + +type Pointer unsafe.Pointer + +// those types are left for compatibility reasons +type GLboolean C.GLboolean +type GLbyte C.GLbyte +type GLshort C.GLshort +type GLint C.GLint +type GLsizei C.GLsizei +type GLubyte C.GLubyte +type GLushort C.GLushort +type GLuint C.GLuint +type GLfloat C.GLfloat +type GLdouble C.GLdouble + +// helpers + +func glBool(v bool) C.GLboolean { + if v { + return 1 + } + + return 0 +} + +func goBool(v C.GLboolean) bool { + return v != 0 +} + +func glString(s string) *C.GLchar { return (*C.GLchar)(C.CString(s)) } + +func freeString(ptr *C.GLchar) { C.free(unsafe.Pointer(ptr)) } + +func ptr(v interface{}) unsafe.Pointer { + + if v == nil { + return unsafe.Pointer(nil) + } + + rv := reflect.ValueOf(v) + var et reflect.Value + switch rv.Type().Kind() { + case reflect.Uintptr: + offset, _ := v.(uintptr) + return unsafe.Pointer(offset) + case reflect.Ptr: + if rv.IsNil() { + return unsafe.Pointer(nil) + } + et = rv.Elem() + case reflect.Slice: + if rv.IsNil() || rv.Len() == 0 { + return unsafe.Pointer(nil) + } + et = rv.Index(0) + default: + panic("type must be a pointer, a slice, uintptr or nil") + } + + return unsafe.Pointer(et.UnsafeAddr()) +} + +/* +uniformMatrix2fv +uniformMatrix2fv +uniformMatrix3fv +uniformMatrix3fv +uniformMatrix4fv +uniformMatrix4fv +*/ + +// Main + +func BlendColor(red GLclampf, green GLclampf, blue GLclampf, alpha GLclampf) { + C.glBlendColor(C.GLclampf(red), C.GLclampf(green), C.GLclampf(blue), C.GLclampf(alpha)) +} + +func BlendEquation(mode GLenum) { C.glBlendEquation(C.GLenum(mode)) } + +func BlendEquationSeparate(modeRGB GLenum, modeAlpha GLenum) { + C.glBlendEquationSeparate(C.GLenum(modeRGB), C.GLenum(modeAlpha)) +} + +func BlendFuncSeparate(srcRGB GLenum, dstRGB GLenum, srcAlpha GLenum, dstAlpha GLenum) { + C.glBlendFuncSeparate(C.GLenum(srcRGB), C.GLenum(dstRGB), C.GLenum(srcAlpha), C.GLenum(dstAlpha)) +} + +func SampleCoverage(value GLclampf, invert bool) { + C.glSampleCoverage(C.GLclampf(value), glBool(invert)) +} + +func StencilFuncSeparate(face GLenum, func_ GLenum, ref int, mask uint) { + C.glStencilFuncSeparate(C.GLenum(face), C.GLenum(func_), C.GLint(ref), C.GLuint(mask)) +} + +func StencilMaskSeparate(face GLenum, mask uint) { + C.glStencilMaskSeparate(C.GLenum(face), C.GLuint(mask)) +} + +func StencilOpSeparate(face GLenum, fail GLenum, zfail GLenum, zpass GLenum) { + C.glStencilOpSeparate(C.GLenum(face), C.GLenum(fail), C.GLenum(zfail), C.GLenum(zpass)) +} + +//void glAccum (GLenum op, float32 value) +func Accum(op GLenum, value float32) { + C.glAccum(C.GLenum(op), C.GLfloat(value)) +} + +//void glAlphaFunc (GLenum func, GLclampf ref) +func AlphaFunc(func_ GLenum, ref GLclampf) { + C.glAlphaFunc(C.GLenum(func_), C.GLclampf(ref)) +} + +//void glArrayElement (int i) +func ArrayElement(i int) { + C.glArrayElement(C.GLint(i)) +} + +//void glBegin (GLenum mode) +func Begin(mode GLenum) { + C.glBegin(C.GLenum(mode)) +} + +//void glBitmap (GLsizei width, int height, float32 xorig, float32 yorig, float32 xmove, float32 ymove, const uint8 *bitmap) +func Bitmap(width int, height int, xorig float32, yorig float32, xmove float32, ymove float32, bitmap *uint8) { + C.glBitmap(C.GLsizei(width), C.GLsizei(height), C.GLfloat(xorig), C.GLfloat(yorig), C.GLfloat(xmove), C.GLfloat(ymove), (*C.GLubyte)(bitmap)) +} + +//void glBlendFunc (GLenum sfactor, GLenum dfactor) +func BlendFunc(sfactor GLenum, dfactor GLenum) { + C.glBlendFunc(C.GLenum(sfactor), C.GLenum(dfactor)) +} + +//void glCallList (uint list) +func CallList(list uint) { + C.glCallList(C.GLuint(list)) +} + +//void glCallLists (GLsizei n, GLenum type, const GLvoid *lists) +func CallLists(n int, typ GLenum, lists interface{}) { + C.glCallLists(C.GLsizei(n), C.GLenum(typ), ptr(lists)) +} + +//void glClear (GLbitfield mask) +func Clear(mask GLbitfield) { + C.glClear(C.GLbitfield(mask)) +} + +//void glClearAccum (float32 red, float32 green, float32 blue, float32 alpha) +func ClearAccum(red float32, green float32, blue float32, alpha float32) { + C.glClearAccum(C.GLfloat(red), C.GLfloat(green), C.GLfloat(blue), C.GLfloat(alpha)) +} + +//void glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +func ClearColor(red GLclampf, green GLclampf, blue GLclampf, alpha GLclampf) { + C.glClearColor(C.GLclampf(red), C.GLclampf(green), C.GLclampf(blue), C.GLclampf(alpha)) +} + +//void glClearDepth (GLclampd depth) +func ClearDepth(depth GLclampd) { + C.glClearDepth(C.GLclampd(depth)) +} + +//void glClearIndex (float32 c) +func ClearIndex(c float32) { + C.glClearIndex(C.GLfloat(c)) +} + +//void glClearStencil (int s) +func ClearStencil(s int) { + C.glClearStencil(C.GLint(s)) +} + +//void glClipPlane (GLenum plane, const float64 *equation) +func ClipPlane(plane GLenum, equation []float64) { + C.glClipPlane(C.GLenum(plane), (*C.GLdouble)(&equation[0])) +} + +//void glCopyPixels (int x, int y, int width, int height, GLenum type) +func CopyPixels(x int, y int, width int, height int, type_ GLenum) { + C.glCopyPixels(C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height), C.GLenum(type_)) +} + +//void glCullFace (GLenum mode) +func CullFace(mode GLenum) { + C.glCullFace(C.GLenum(mode)) +} + +//void glDeleteLists (uint list, int range) +func DeleteLists(list uint, range_ int) { + C.glDeleteLists(C.GLuint(list), C.GLsizei(range_)) +} + +//void glDepthFunc (GLenum func) +func DepthFunc(func_ GLenum) { + C.glDepthFunc(C.GLenum(func_)) +} + +//void glDepthMask (bool flag) +func DepthMask(flag bool) { + C.glDepthMask(glBool(flag)) +} + +//void glDepthRange (GLclampd zNear, GLclampd zFar) +func DepthRange(zNear GLclampd, zFar GLclampd) { + C.glDepthRange(C.GLclampd(zNear), C.GLclampd(zFar)) +} + +//void glDisable (GLenum cap) +func Disable(cap GLenum) { + C.glDisable(C.GLenum(cap)) +} + +//void glDisableClientState (GLenum array) +func DisableClientState(array GLenum) { + C.glDisableClientState(C.GLenum(array)) +} + +//void glDrawArrays (GLenum mode, int first, int count) +func DrawArrays(mode GLenum, first int, count int) { + C.glDrawArrays(C.GLenum(mode), C.GLint(first), C.GLsizei(count)) +} + +//void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount) +func DrawArraysInstanced(mode GLenum, first int, count, primcount int) { + C.glDrawArraysInstanced(C.GLenum(mode), C.GLint(first), C.GLsizei(count), C.GLsizei(primcount)) +} + +//void glDrawBuffer (GLenum mode) +func DrawBuffer(mode GLenum) { + C.glDrawBuffer(C.GLenum(mode)) +} + +// //void glDrawBuffers(GLsizei n, const GLenum *bufs) +func DrawBuffers(n int, bufs []GLenum) { + C.glDrawBuffers(C.GLsizei(n), (*C.GLenum)(&bufs[0])) +} + +//void glDrawElements (GLenum mode, int count, GLenum type, const GLvoid *indices) +func DrawElements(mode GLenum, count int, typ GLenum, indices interface{}) { + C.glDrawElements(C.GLenum(mode), C.GLsizei(count), C.GLenum(typ), + ptr(indices)) +} + +//void glDrawRangeElements (GLenum mode, int start, int end, int count, GLenum type, const GLvoid *indices) +func DrawRangeElements(mode GLenum, start, end uint, count int, typ GLenum, indices interface{}) { + C.glDrawRangeElements(C.GLenum(mode), C.GLuint(start), C.GLuint(end), C.GLsizei(count), C.GLenum(typ), + ptr(indices)) +} + +//void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount) +func DrawElementsInstanced(mode GLenum, count int, typ GLenum, indices interface{}, primcount int) { + C.glDrawElementsInstanced(C.GLenum(mode), C.GLsizei(count), C.GLenum(typ), + ptr(indices), C.GLsizei(primcount)) +} + +//void glDrawElementsBaseVertex(GLenum mode, int count, GLenum type, GLvoid *indices, int basevertex) +func DrawElementsBaseVertex(mode GLenum, count int, typ GLenum, indices interface{}, basevertex int) { + C.glDrawElementsBaseVertex(C.GLenum(mode), C.GLsizei(count), + C.GLenum(typ), ptr(indices), C.GLint(basevertex)) +} + +//void glDrawPixels (GLsizei width, int height, GLenum format, GLenum type, const GLvoid *pixels) +func DrawPixels(width int, height int, format, typ GLenum, pixels interface{}) { + C.glDrawPixels(C.GLsizei(width), C.GLsizei(height), C.GLenum(format), + C.GLenum(typ), ptr(pixels)) +} + +//void glEdgeFlag (bool flag) +func EdgeFlag(flag bool) { + C.glEdgeFlag(glBool(flag)) +} + +//void glEdgeFlagPointer (GLsizei stride, const GLvoid *pointer) +func EdgeFlagPointer(stride int, pointer unsafe.Pointer) { + C.glEdgeFlagPointer(C.GLsizei(stride), pointer) +} + +//void glEdgeFlagv (const bool *flag) +func EdgeFlagv(flag []bool) { + if len(flag) > 0 { + C.glEdgeFlagv((*C.GLboolean)(unsafe.Pointer(&flag[0]))) + } +} + +//void glEnable (GLenum cap) +func Enable(cap GLenum) { + C.glEnable(C.GLenum(cap)) +} + +//void glEnableClientState (GLenum array) +func EnableClientState(array GLenum) { + C.glEnableClientState(C.GLenum(array)) +} + +//void glEnd (void) +func End() { + C.glEnd() +} + +//void glEndList (void) +func EndList() { + C.glEndList() +} + +//void glEvalCoord1d (float64 u) +func EvalCoord1d(u float64) { + C.glEvalCoord1d(C.GLdouble(u)) +} + +//void glEvalCoord1dv (const float64 *u) +func EvalCoord1dv(u *float64) { + C.glEvalCoord1dv((*C.GLdouble)(u)) +} + +//void glEvalCoord1f (float32 u) +func EvalCoord1f(u float32) { + C.glEvalCoord1f(C.GLfloat(u)) +} + +//void glEvalCoord1fv (const float *u) +func EvalCoord1fv(u *[1]float32) { + C.glEvalCoord1fv((*C.GLfloat)(&u[0])) +} + +//void glEvalCoord2d (float64 u, float64 v) +func EvalCoord2d(u float64, v float64) { + C.glEvalCoord2d(C.GLdouble(u), C.GLdouble(v)) +} + +//void glEvalCoord2dv (const float64 *u) +func EvalCoord2dv(u *float64) { + C.glEvalCoord2dv((*C.GLdouble)(u)) +} + +//void glEvalCoord2f (float32 u, float32 v) +func EvalCoord2f(u float32, v float32) { + C.glEvalCoord2f(C.GLfloat(u), C.GLfloat(v)) +} + +//void glEvalCoord2fv (const float *u) +func EvalCoord2fv(u *[2]float32) { + C.glEvalCoord2fv((*C.GLfloat)(&u[0])) +} + +//void glEvalMesh1 (GLenum mode, int i1, int i2) +func EvalMesh1(mode GLenum, i1 int, i2 int) { + C.glEvalMesh1(C.GLenum(mode), C.GLint(i1), C.GLint(i2)) +} + +//void glEvalMesh2 (GLenum mode, int i1, int i2, int j1, int j2) +func EvalMesh2(mode GLenum, i1 int, i2 int, j1 int, j2 int) { + C.glEvalMesh2(C.GLenum(mode), C.GLint(i1), C.GLint(i2), C.GLint(j1), C.GLint(j2)) +} + +//void glEvalPoint1 (int i) +func EvalPoint1(i int) { + C.glEvalPoint1(C.GLint(i)) +} + +//void glEvalPoint2 (int i, int j) +func EvalPoint2(i int, j int) { + C.glEvalPoint2(C.GLint(i), C.GLint(j)) +} + +//void glFeedbackBuffer (GLsizei size, GLenum type, float32 *buffer) +func FeedbackBuffer(size int, type_ GLenum, buffer *float32) { + C.glFeedbackBuffer(C.GLsizei(size), C.GLenum(type_), (*C.GLfloat)(buffer)) +} + +//void glFinish (void) +func Finish() { + C.glFinish() +} + +//void glFlush (void) +func Flush() { + C.glFlush() +} + +//void glFogf (GLenum pname, float32 param) +func Fogf(pname GLenum, param float32) { + C.glFogf(C.GLenum(pname), C.GLfloat(param)) +} + +//void glFogfv (GLenum pname, const float *params) +func Fogfv(pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glFogfv(C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glFogi (GLenum pname, int param) +func Fogi(pname GLenum, param int) { + C.glFogi(C.GLenum(pname), C.GLint(param)) +} + +//void glFogiv (GLenum pname, const int *params) +func Fogiv(pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glFogiv(C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glFrontFace (GLenum mode) +func FrontFace(mode GLenum) { + C.glFrontFace(C.GLenum(mode)) +} + +//uint glGenLists (GLsizei range) +func GenLists(range_ int) uint { + return uint(C.glGenLists(C.GLsizei(range_))) +} + +//void glGetBooleanv (GLenum pname, bool *params) +func GetBooleanv(pname GLenum, params []bool) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glGetBooleanv(C.GLenum(pname), (*C.GLboolean)(unsafe.Pointer(¶ms[0]))) +} + +// Convenience function for GetBooleanv +func GetBoolean4(pname GLenum) (v0, v1, v2, v3 bool) { + var values [4]C.GLboolean + C.glGetBooleanv(C.GLenum(pname), &values[0]) + v0 = values[0] != 0 + v1 = values[1] != 0 + v2 = values[2] != 0 + v3 = values[3] != 0 + return +} + +//void glGetClipPlane (GLenum plane, float64 *equation) +func GetClipPlane(plane GLenum, equation *float64) { + C.glGetClipPlane(C.GLenum(plane), (*C.GLdouble)(equation)) +} + +//void glGetDoublev (GLenum pname, float64 *params) +func GetDoublev(pname GLenum, params []float64) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glGetDoublev(C.GLenum(pname), (*C.GLdouble)(¶ms[0])) +} + +// Convenience function for GetDoublev +func GetDouble4(pname GLenum) (v0, v1, v2, v3 float64) { + var values [4]C.GLdouble + C.glGetDoublev(C.GLenum(pname), &values[0]) + v0 = float64(values[0]) + v1 = float64(values[1]) + v2 = float64(values[2]) + v3 = float64(values[3]) + return +} + +//GLenum glGetError (void) +func GetError() GLenum { + return GLenum(C.glGetError()) +} + +//void glGetFloatv (GLenum pname, float *params) +func GetFloatv(pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glGetFloatv(C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +// Convenience function for GetFloatv +func GetFloat4(pname GLenum) (v0, v1, v2, v3 float32) { + var values [4]C.GLfloat + C.glGetFloatv(C.GLenum(pname), &values[0]) + v0 = float32(values[0]) + v1 = float32(values[1]) + v2 = float32(values[2]) + v3 = float32(values[3]) + return +} + +//void glGetIntegerv (GLenum pname, int *params) +func GetIntegerv(pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glGetIntegerv(C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +// Convenience function for glGetIntegerv +func GetInteger4(pname GLenum) (v0, v1, v2, v3 int) { + var values [4]C.GLint + C.glGetIntegerv(C.GLenum(pname), &values[0]) + v0 = int(values[0]) + v1 = int(values[1]) + v2 = int(values[2]) + v3 = int(values[3]) + return +} + +//void glGetLightfv (GLenum light, GLenum pname, float *params) +func GetLightfv(light GLenum, pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glGetLightfv(C.GLenum(light), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glGetLightiv (GLenum light, GLenum pname, int *params) +func GetLightiv(light GLenum, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glGetLightiv(C.GLenum(light), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glGetMapdv (GLenum target, GLenum query, float64 *v) +func GetMapdv(target GLenum, query GLenum, v []float64) { + if len(v) == 0 { + panic("Invalid slice length") + } + C.glGetMapdv(C.GLenum(target), C.GLenum(query), (*C.GLdouble)(&v[0])) +} + +//void glGetMapfv (GLenum target, GLenum query, float *v) +func GetMapfv(target GLenum, query GLenum, v []float32) { + if len(v) == 0 { + panic("Invalid slice length") + } + C.glGetMapfv(C.GLenum(target), C.GLenum(query), (*C.GLfloat)(&v[0])) +} + +//void glGetMapiv (GLenum target, GLenum query, int *v) +func GetMapiv(target GLenum, query GLenum, v []int32) { + if len(v) == 0 { + panic("Invalid slice length") + } + C.glGetMapiv(C.GLenum(target), C.GLenum(query), (*C.GLint)(&v[0])) +} + +//void glGetMaterialfv (GLenum face, GLenum pname, float *params) +func GetMaterialfv(face GLenum, pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glGetMaterialfv(C.GLenum(face), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glGetMaterialiv (GLenum face, GLenum pname, int *params) +func GetMaterialiv(face GLenum, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glGetMaterialiv(C.GLenum(face), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glGetPixelMapfv (GLenum map, float *values) +func GetPixelMapfv(map_ GLenum, values []float32) { + if len(values) == 0 { + panic("Invalid values length") + } + C.glGetPixelMapfv(C.GLenum(map_), (*C.GLfloat)(&values[0])) +} + +//void glGetPixelMapuiv (GLenum map, uint *values) +func GetPixelMapuiv(map_ GLenum, values *uint32) { + C.glGetPixelMapuiv(C.GLenum(map_), (*C.GLuint)(values)) +} + +//void glGetPixelMapusv (GLenum map, uint16 *values) +func GetPixelMapusv(map_ GLenum, values *uint16) { + C.glGetPixelMapusv(C.GLenum(map_), (*C.GLushort)(values)) +} + +//void glGetPointerv (GLenum pname, GLvoid* *params) +func GetPointerv(pname GLenum, params []unsafe.Pointer) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glGetPointerv(C.GLenum(pname), ¶ms[0]) +} + +//void glGetPolygonStipple (uint8 *mask) +func GetPolygonStipple(mask *uint8) { + C.glGetPolygonStipple((*C.GLubyte)(mask)) +} + +//const uint8 * glGetString (GLenum name) +func GetString(name GLenum) string { + s := unsafe.Pointer(C.glGetString(C.GLenum(name))) + return C.GoString((*C.char)(s)) +} + +//void glHint (GLenum target, GLenum mode) +func Hint(target GLenum, mode GLenum) { + C.glHint(C.GLenum(target), C.GLenum(mode)) +} + +//void glIndexMask (uint mask) +func IndexMask(mask uint) { + C.glIndexMask(C.GLuint(mask)) +} + +//void glIndexPointer (GLenum type, int stride, const GLvoid *pointer) +func IndexPointer(typ GLenum, stride int, pointer interface{}) { + C.glIndexPointer(C.GLenum(typ), C.GLsizei(stride), ptr(pointer)) +} + +//void glIndexd (float64 c) +func Indexd(c float64) { + C.glIndexd(C.GLdouble(c)) +} + +//void glIndexdv (const float64 *c) +func Indexdv(c *[1]float64) { + C.glIndexdv((*C.GLdouble)(&c[0])) +} + +//void glIndexf (float32 c) +func Indexf(c float32) { + C.glIndexf(C.GLfloat(c)) +} + +//void glIndexfv (const float32 *c) +func Indexfv(c *[1]float32) { + C.glIndexfv((*C.GLfloat)(&c[0])) +} + +//void glIndexi (int c) +func Indexi(c int) { + C.glIndexi(C.GLint(c)) +} + +//void glIndexiv (const int *c) +func Indexiv(c *[1]int32) { + C.glIndexiv((*C.GLint)(&c[0])) +} + +//void glIndexs (int16 c) +func Indexs(c int16) { + C.glIndexs(C.GLshort(c)) +} + +//void glIndexsv (const int16 *c) +func Indexsv(c *[1]int16) { + C.glIndexsv((*C.GLshort)(&c[0])) +} + +//void glIndexub (uint8 c) +func Indexub(c uint8) { + C.glIndexub(C.GLubyte(c)) +} + +//void glIndexubv (const uint8 *c) +func Indexubv(c *[1]uint8) { + C.glIndexubv((*C.GLubyte)(&c[0])) +} + +//void glInitNames (void) +func InitNames() { + C.glInitNames() +} + +//void glInterleavedArrays (GLenum format, int stride, const GLvoid *pointer) +func InterleavedArrays(format GLenum, stride int, pointer unsafe.Pointer) { + C.glInterleavedArrays(C.GLenum(format), C.GLsizei(stride), pointer) +} + +//bool glIsEnabled (GLenum cap) +func IsEnabled(cap GLenum) bool { + return goBool(C.glIsEnabled(C.GLenum(cap))) +} + +//bool glIsList (uint list) +func IsList(list uint) bool { + return goBool(C.glIsList(C.GLuint(list))) +} + +//void glLightModelf (GLenum pname, float32 param) +func LightModelf(pname GLenum, param float32) { + C.glLightModelf(C.GLenum(pname), C.GLfloat(param)) +} + +//void glLightModelfv (GLenum pname, const float *params) +func LightModelfv(pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glLightModelfv(C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glLightModeli (GLenum pname, int param) +func LightModeli(pname GLenum, param int) { + C.glLightModeli(C.GLenum(pname), C.GLint(param)) +} + +//void glLightModeliv (GLenum pname, const int *params) +func LightModeliv(pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glLightModeliv(C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glLightf (GLenum light, GLenum pname, float32 param) +func Lightf(light GLenum, pname GLenum, param float32) { + C.glLightf(C.GLenum(light), C.GLenum(pname), C.GLfloat(param)) +} + +//void glLightfv (GLenum light, GLenum pname, const float *params) +func Lightfv(light GLenum, pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glLightfv(C.GLenum(light), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glLighti (GLenum light, GLenum pname, int param) +func Lighti(light GLenum, pname GLenum, param int) { + C.glLighti(C.GLenum(light), C.GLenum(pname), C.GLint(param)) +} + +//void glLightiv (GLenum light, GLenum pname, const int *params) +func Lightiv(light GLenum, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glLightiv(C.GLenum(light), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glLineStipple (int factor, uint16 pattern) +func LineStipple(factor int, pattern uint16) { + C.glLineStipple(C.GLint(factor), C.GLushort(pattern)) +} + +//void glLineWidth (float32 width) +func LineWidth(width float32) { + C.glLineWidth(C.GLfloat(width)) +} + +//void glListBase (uint base) +func ListBase(base uint) { + C.glListBase(C.GLuint(base)) +} + +//void glLoadName (uint name) +func LoadName(name uint) { + C.glLoadName(C.GLuint(name)) +} + +//void glLogicOp (GLenum opcode) +func LogicOp(opcode GLenum) { + C.glLogicOp(C.GLenum(opcode)) +} + +//void glMap1d (GLenum target, float64 u1, float64 u2, int stride, int order, const float64 *points) +func Map1d(target GLenum, u1 float64, u2 float64, stride int, order int, points []float64) { + if len(points) == 0 { + panic("Invalid points size") + } + C.glMap1d(C.GLenum(target), C.GLdouble(u1), C.GLdouble(u2), + C.GLint(stride), C.GLint(order), (*C.GLdouble)(&points[0])) +} + +//void glMap1f (GLenum target, float32 u1, float32 u2, int stride, int order, const float32 *points) +func Map1f(target GLenum, u1 float32, u2 float32, stride int, order int, points []float32) { + if len(points) == 0 { + panic("Invalid points size") + } + C.glMap1f(C.GLenum(target), C.GLfloat(u1), C.GLfloat(u2), C.GLint(stride), + C.GLint(order), (*C.GLfloat)(&points[0])) +} + +//void glMap2d (GLenum target, float64 u1, float64 u2, int ustride, int uorder, float64 v1, float64 v2, int vstride, int vorder, const float64 *points) +func Map2d(target GLenum, u1 float64, u2 float64, ustride int, uorder int, v1 float64, v2 float64, vstride int, vorder int, points []float64) { + if len(points) == 0 { + panic("Invalid points size") + } + C.glMap2d(C.GLenum(target), C.GLdouble(u1), C.GLdouble(u2), C.GLint(ustride), + C.GLint(uorder), C.GLdouble(v1), C.GLdouble(v2), C.GLint(vstride), + C.GLint(vorder), (*C.GLdouble)(&points[0])) +} + +//void glMap2f (GLenum target, float32 u1, float32 u2, int ustride, int uorder, float32 v1, float32 v2, int vstride, int vorder, const float32 *points) +func Map2f(target GLenum, u1 float32, u2 float32, ustride int, uorder int, v1 float32, v2 float32, vstride int, vorder int, points []float32) { + if len(points) == 0 { + panic("Invalid points size") + } + C.glMap2f(C.GLenum(target), C.GLfloat(u1), C.GLfloat(u2), C.GLint(ustride), + C.GLint(uorder), C.GLfloat(v1), C.GLfloat(v2), C.GLint(vstride), + C.GLint(vorder), (*C.GLfloat)(&points[0])) +} + +//void glMapGrid1d (int un, float64 u1, float64 u2) +func MapGrid1d(un int, u1 float64, u2 float64) { + C.glMapGrid1d(C.GLint(un), C.GLdouble(u1), C.GLdouble(u2)) +} + +//void glMapGrid1f (int un, float32 u1, float32 u2) +func MapGrid1f(un int, u1 float32, u2 float32) { + C.glMapGrid1f(C.GLint(un), C.GLfloat(u1), C.GLfloat(u2)) +} + +//void glMapGrid2d (int un, float64 u1, float64 u2, int vn, float64 v1, float64 v2) +func MapGrid2d(un int, u1 float64, u2 float64, vn int, v1 float64, v2 float64) { + C.glMapGrid2d(C.GLint(un), C.GLdouble(u1), C.GLdouble(u2), C.GLint(vn), C.GLdouble(v1), C.GLdouble(v2)) +} + +//void glMapGrid2f (int un, float32 u1, float32 u2, int vn, float32 v1, float32 v2) +func MapGrid2f(un int, u1 float32, u2 float32, vn int, v1 float32, v2 float32) { + C.glMapGrid2f(C.GLint(un), C.GLfloat(u1), C.GLfloat(u2), C.GLint(vn), C.GLfloat(v1), C.GLfloat(v2)) +} + +//void glMaterialf (GLenum face, GLenum pname, float32 param) +func Materialf(face GLenum, pname GLenum, param float32) { + C.glMaterialf(C.GLenum(face), C.GLenum(pname), C.GLfloat(param)) +} + +//void glMaterialfv (GLenum face, GLenum pname, const float *params) +func Materialfv(face GLenum, pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glMaterialfv(C.GLenum(face), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glMateriali (GLenum face, GLenum pname, int param) +func Materiali(face GLenum, pname GLenum, param int) { + C.glMateriali(C.GLenum(face), C.GLenum(pname), C.GLint(param)) +} + +//void glMaterialiv (GLenum face, GLenum pname, const int *params) +func Materialiv(face GLenum, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params length") + } + C.glMaterialiv(C.GLenum(face), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glNewList (uint list, GLenum mode) +func NewList(list uint, mode GLenum) { + C.glNewList(C.GLuint(list), C.GLenum(mode)) +} + +//void glNormal3b (int8 nx, int8 ny, int8 nz) +func Normal3b(nx int8, ny int8, nz int8) { + C.glNormal3b(C.GLbyte(nx), C.GLbyte(ny), C.GLbyte(nz)) +} + +//void glNormal3bv (const int8 *v) +func Normal3bv(v *[3]int8) { + C.glNormal3bv((*C.GLbyte)(&v[0])) +} + +//void glNormal3d (float64 nx, float64 ny, float64 nz) +func Normal3d(nx float64, ny float64, nz float64) { + C.glNormal3d(C.GLdouble(nx), C.GLdouble(ny), C.GLdouble(nz)) +} + +//void glNormal3dv (const float64 *v) +func Normal3dv(v *[3]float64) { + C.glNormal3dv((*C.GLdouble)(&v[0])) +} + +//void glNormal3f (float32 nx, float32 ny, float32 nz) +func Normal3f(nx float32, ny float32, nz float32) { + C.glNormal3f(C.GLfloat(nx), C.GLfloat(ny), C.GLfloat(nz)) +} + +//void glNormal3fv (const float *v) +func Normal3fv(v *[3]float32) { + C.glNormal3fv((*C.GLfloat)(&v[0])) +} + +//void glNormal3i (int nx, int ny, int nz) +func Normal3i(nx int, ny int, nz int) { + C.glNormal3i(C.GLint(nx), C.GLint(ny), C.GLint(nz)) +} + +//void glNormal3iv (const int *v) +func Normal3iv(v *[3]int32) { + C.glNormal3iv((*C.GLint)(&v[0])) +} + +//void glNormal3s (int16 nx, int16 ny, int16 nz) +func Normal3s(nx int16, ny int16, nz int16) { + C.glNormal3s(C.GLshort(nx), C.GLshort(ny), C.GLshort(nz)) +} + +//void glNormal3sv (const int16 *v) +func Normal3sv(v *[3]int16) { + C.glNormal3sv((*C.GLshort)(&v[0])) +} + +//void glNormalPointer (GLenum type, int stride, const GLvoid *pointer) +func NormalPointer(typ GLenum, stride int, pointer interface{}) { + C.glNormalPointer(C.GLenum(typ), C.GLsizei(stride), ptr(pointer)) +} + +//void glPassThrough (float32 token) +func PassThrough(token float32) { + C.glPassThrough(C.GLfloat(token)) +} + +//void glPixelStoref (GLenum pname, float param) +func PixelStoref(pname GLenum, param float32) { + C.glPixelStoref(C.GLenum(pname), C.GLfloat(param)) +} + +//void glPixelStorei (GLenum pname, int param) +func PixelStorei(pname GLenum, param int) { + C.glPixelStorei(C.GLenum(pname), C.GLint(param)) +} + +//void glPixelTransferf (GLenum pname, float32 param) +func PixelTransferf(pname GLenum, param float32) { + C.glPixelTransferf(C.GLenum(pname), C.GLfloat(param)) +} + +//void glPixelTransferi (GLenum pname, int param) +func PixelTransferi(pname GLenum, param int) { + C.glPixelTransferi(C.GLenum(pname), C.GLint(param)) +} + +//void glPixelZoom (float32 xfactor, float32 yfactor) +func PixelZoom(xfactor float32, yfactor float32) { + C.glPixelZoom(C.GLfloat(xfactor), C.GLfloat(yfactor)) +} + +//void glPointSize (float32 size) +func PointSize(size float32) { + C.glPointSize(C.GLfloat(size)) +} + +//void glPolygonMode (GLenum face, GLenum mode) +func PolygonMode(face GLenum, mode GLenum) { + C.glPolygonMode(C.GLenum(face), C.GLenum(mode)) +} + +//void glPolygonOffset (float32 factor, float32 units) +func PolygonOffset(factor float32, units float32) { + C.glPolygonOffset(C.GLfloat(factor), C.GLfloat(units)) +} + +//void glPolygonStipple (const uint8 *mask) +func PolygonStipple(mask *uint8) { + C.glPolygonStipple((*C.GLubyte)(mask)) +} + +//void glPopAttrib (void) +func PopAttrib() { + C.glPopAttrib() +} + +//void glPopClientAttrib (void) +func PopClientAttrib() { + C.glPopClientAttrib() +} + +//void glPopName (void) +func PopName() { + C.glPopName() +} + +//void glPrimitiveRestartIndex(GLuint index) +func PrimitiveRestartIndex(index GLuint) { + C.glPrimitiveRestartIndex(C.GLuint(index)) +} + +//void glPushAttrib (GLbitfield mask) +func PushAttrib(mask GLbitfield) { + C.glPushAttrib(C.GLbitfield(mask)) +} + +//void glPushClientAttrib (GLbitfield mask) +func PushClientAttrib(mask GLbitfield) { + C.glPushClientAttrib(C.GLbitfield(mask)) +} + +//void glPushName (uint name) +func PushName(name uint) { + C.glPushName(C.GLuint(name)) +} + +//void glRasterPos2d (float64 x, float64 y) +func RasterPos2d(x float64, y float64) { + C.glRasterPos2d(C.GLdouble(x), C.GLdouble(y)) +} + +//void glRasterPos2dv (const float64 *v) +func RasterPos2dv(v *[2]float64) { + C.glRasterPos2dv((*C.GLdouble)(&v[0])) +} + +//void glRasterPos2f (float32 x, float32 y) +func RasterPos2f(x float32, y float32) { + C.glRasterPos2f(C.GLfloat(x), C.GLfloat(y)) +} + +//void glRasterPos2fv (const float *v) +func RasterPos2fv(v *[2]float32) { + C.glRasterPos2fv((*C.GLfloat)(&v[0])) +} + +//void glRasterPos2i (int x, int y) +func RasterPos2i(x int, y int) { + C.glRasterPos2i(C.GLint(x), C.GLint(y)) +} + +//void glRasterPos2iv (const int *v) +func RasterPos2iv(v *[2]int32) { + C.glRasterPos2iv((*C.GLint)(&v[0])) +} + +//void glRasterPos2s (int16 x, int16 y) +func RasterPos2s(x int16, y int16) { + C.glRasterPos2s(C.GLshort(x), C.GLshort(y)) +} + +//void glRasterPos2sv (const int16 *v) +func RasterPos2sv(v *[2]int16) { + C.glRasterPos2sv((*C.GLshort)(&v[0])) +} + +//void glRasterPos3d (float64 x, float64 y, float64 z) +func RasterPos3d(x float64, y float64, z float64) { + C.glRasterPos3d(C.GLdouble(x), C.GLdouble(y), C.GLdouble(z)) +} + +//void glRasterPos3dv (const float64 *v) +func RasterPos3dv(v *[3]float64) { + C.glRasterPos3dv((*C.GLdouble)(&v[0])) +} + +//void glRasterPos3f (float32 x, float32 y, float32 z) +func RasterPos3f(x float32, y float32, z float32) { + C.glRasterPos3f(C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) +} + +//void glRasterPos3fv (const float *v) +func RasterPos3fv(v *[3]float32) { + C.glRasterPos3fv((*C.GLfloat)(&v[0])) +} + +//void glRasterPos3i (int x, int y, int z) +func RasterPos3i(x int, y int, z int) { + C.glRasterPos3i(C.GLint(x), C.GLint(y), C.GLint(z)) +} + +//void glRasterPos3iv (const int *v) +func RasterPos3iv(v *[3]int32) { + C.glRasterPos3iv((*C.GLint)(&v[0])) +} + +//void glRasterPos3s (int16 x, int16 y, int16 z) +func RasterPos3s(x int16, y int16, z int16) { + C.glRasterPos3s(C.GLshort(x), C.GLshort(y), C.GLshort(z)) +} + +//void glRasterPos3sv (const int16 *v) +func RasterPos3sv(v *[3]int16) { + C.glRasterPos3sv((*C.GLshort)(&v[0])) +} + +//void glRasterPos4d (float64 x, float64 y, float64 z, float64 w) +func RasterPos4d(x float64, y float64, z float64, w float64) { + C.glRasterPos4d(C.GLdouble(x), C.GLdouble(y), C.GLdouble(z), C.GLdouble(w)) +} + +//void glRasterPos4dv (const float64 *v) +func RasterPos4dv(v *[3]float64) { + C.glRasterPos4dv((*C.GLdouble)(&v[0])) +} + +//void glRasterPos4f (float32 x, float32 y, float32 z, float32 w) +func RasterPos4f(x float32, y float32, z float32, w float32) { + C.glRasterPos4f(C.GLfloat(x), C.GLfloat(y), C.GLfloat(z), C.GLfloat(w)) +} + +//void glRasterPos4fv (const float *v) +func RasterPos4fv(v *[4]float32) { + C.glRasterPos4fv((*C.GLfloat)(&v[0])) +} + +//void glRasterPos4i (int x, int y, int z, int w) +func RasterPos4i(x int, y int, z int, w int) { + C.glRasterPos4i(C.GLint(x), C.GLint(y), C.GLint(z), C.GLint(w)) +} + +//void glRasterPos4iv (const int *v) +func RasterPos4iv(v *[4]int32) { + C.glRasterPos4iv((*C.GLint)(&v[0])) +} + +//void glRasterPos4s (int16 x, int16 y, int16 z, int16 w) +func RasterPos4s(x int16, y int16, z int16, w int16) { + C.glRasterPos4s(C.GLshort(x), C.GLshort(y), C.GLshort(z), C.GLshort(w)) +} + +//void glRasterPos4sv (const int16 *v) +func RasterPos4sv(v *[4]int16) { + C.glRasterPos4sv((*C.GLshort)(&v[0])) +} + +//void glReadBuffer (GLenum mode) +func ReadBuffer(mode GLenum) { + C.glReadBuffer(C.GLenum(mode)) +} + +//void glReadPixels (int x, int y, int width, int height, GLenum format, GLenum type, GLvoid *pixels) +func ReadPixels(x int, y int, width int, height int, format, typ GLenum, pixels interface{}) { + C.glReadPixels(C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height), + C.GLenum(format), C.GLenum(typ), ptr(pixels)) +} + +//void glRectd (float64 x1, float64 y1, float64 x2, float64 y2) +func Rectd(x1 float64, y1 float64, x2 float64, y2 float64) { + C.glRectd(C.GLdouble(x1), C.GLdouble(y1), C.GLdouble(x2), C.GLdouble(y2)) +} + +//void glRectdv (const float64 *v1, const float64 *v2) +func Rectdv(a, b *[2]float64) { + C.glRectdv((*C.GLdouble)(&a[0]), (*C.GLdouble)(&b[0])) +} + +//void glRectf (float32 x1, float32 y1, float32 x2, float32 y2) +func Rectf(x1 float32, y1 float32, x2 float32, y2 float32) { + C.glRectf(C.GLfloat(x1), C.GLfloat(y1), C.GLfloat(x2), C.GLfloat(y2)) +} + +//void glRectfv (const float *v1, const float *v2) +func Rectfv(a, b *[2]float32) { + C.glRectfv((*C.GLfloat)(&a[0]), (*C.GLfloat)(&b[0])) +} + +//void glRecti (int x1, int y1, int x2, int y2) +func Recti(x1 int, y1 int, x2 int, y2 int) { + C.glRecti(C.GLint(x1), C.GLint(y1), C.GLint(x2), C.GLint(y2)) +} + +//void glRectiv (const int *v1, const int *v2) +func Rectiv(a, b *[2]int32) { + C.glRectiv((*C.GLint)(&a[0]), (*C.GLint)(&b[0])) +} + +//void glRects (int16 x1, int16 y1, int16 x2, int16 y2) +func Rects(x1 int16, y1 int16, x2 int16, y2 int16) { + C.glRects(C.GLshort(x1), C.GLshort(y1), C.GLshort(x2), C.GLshort(y2)) +} + +//void glRectsv (const int16 *v1, const int16 *v2) +func Rectsv(a, b *[2]int16) { + C.glRectsv((*C.GLshort)(&a[0]), (*C.GLshort)(&b[0])) +} + +//int glRenderMode (GLenum mode) +func RenderMode(mode GLenum) int { + return int(C.glRenderMode(C.GLenum(mode))) +} + +//void glScissor (int x, int y, int width, int height) +func Scissor(x int, y int, width int, height int) { + C.glScissor(C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height)) +} + +//void glSelectBuffer (GLsizei size, uint *buffer) +func SelectBuffer(buffer []uint32) { + if len(buffer) > 0 { + C.glSelectBuffer(C.GLsizei(len(buffer)), (*C.GLuint)(&buffer[0])) + } +} + +//void glShadeModel (GLenum mode) +func ShadeModel(mode GLenum) { + C.glShadeModel(C.GLenum(mode)) +} + +//void glStencilFunc (GLenum func, int ref, uint mask) +func StencilFunc(func_ GLenum, ref int, mask uint) { + C.glStencilFunc(C.GLenum(func_), C.GLint(ref), C.GLuint(mask)) +} + +//void glStencilMask (uint mask) +func StencilMask(mask uint) { + C.glStencilMask(C.GLuint(mask)) +} + +//void glStencilOp (GLenum fail, GLenum zfail, GLenum zpass) +func StencilOp(fail GLenum, zfail GLenum, zpass GLenum) { + C.glStencilOp(C.GLenum(fail), C.GLenum(zfail), C.GLenum(zpass)) +} + +//void glViewport (int x, int y, int width, int height) +func Viewport(x int, y int, width int, height int) { + C.glViewport(C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height)) +} + +// void glGetFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname, GLint* params); +//func GetFramebufferAttachmentParameter (target, attachment, pname GLenum, params []int32) { +// if len(params) == 0 { +// panic("Invalid params size") +// } +// C.glGetFramebufferAttachmentParameter (C.GLenum(target), C.GLenum(attachment), +// C.GLenum(pname), (*C.GLint)(¶ms[0])) +//} + +func Init() GLenum { + C.SetGlewExperimental(C.GLboolean(1)) + return GLenum(C.glewInit()) +} diff --git a/vendor/github.com/go-gl-legacy/gl/gl.h b/vendor/github.com/go-gl-legacy/gl/gl.h new file mode 100644 index 0000000..17e42c7 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/gl.h @@ -0,0 +1,5 @@ +#include +#include + +#undef GLEW_GET_FUN +#define GLEW_GET_FUN(x) (*x) \ No newline at end of file diff --git a/vendor/github.com/go-gl-legacy/gl/gl_defs.go b/vendor/github.com/go-gl-legacy/gl/gl_defs.go new file mode 100644 index 0000000..7e56e18 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/gl_defs.go @@ -0,0 +1,1365 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include +import "C" + +// Constants +const ( + GL_2_BYTES = C.GL_2_BYTES + GL_2D = C.GL_2D + GL_3_BYTES = C.GL_3_BYTES + GL_3D_COLOR_TEXTURE = C.GL_3D_COLOR_TEXTURE + GL_3D_COLOR = C.GL_3D_COLOR + GL_3D = C.GL_3D + GL_4_BYTES = C.GL_4_BYTES + GL_4D_COLOR_TEXTURE = C.GL_4D_COLOR_TEXTURE + ACCUM_ALPHA_BITS = C.GL_ACCUM_ALPHA_BITS + ACCUM_BLUE_BITS = C.GL_ACCUM_BLUE_BITS + ACCUM_BUFFER_BIT = C.GL_ACCUM_BUFFER_BIT + ACCUM_CLEAR_VALUE = C.GL_ACCUM_CLEAR_VALUE + ACCUM_GREEN_BITS = C.GL_ACCUM_GREEN_BITS + ACCUM_RED_BITS = C.GL_ACCUM_RED_BITS + ACCUM = C.GL_ACCUM + ACTIVE_ATTRIBUTE_MAX_LENGTH = C.GL_ACTIVE_ATTRIBUTE_MAX_LENGTH + ACTIVE_ATTRIBUTES = C.GL_ACTIVE_ATTRIBUTES + ACTIVE_TEXTURE = C.GL_ACTIVE_TEXTURE + ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH = C.GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH + ACTIVE_UNIFORM_BLOCKS = C.GL_ACTIVE_UNIFORM_BLOCKS + ACTIVE_UNIFORM_MAX_LENGTH = C.GL_ACTIVE_UNIFORM_MAX_LENGTH + ACTIVE_UNIFORMS = C.GL_ACTIVE_UNIFORMS + ADD_SIGNED = C.GL_ADD_SIGNED + ADD = C.GL_ADD + ALIASED_LINE_WIDTH_RANGE = C.GL_ALIASED_LINE_WIDTH_RANGE + ALIASED_POINT_SIZE_RANGE = C.GL_ALIASED_POINT_SIZE_RANGE + ALL_ATTRIB_BITS = C.GL_ALL_ATTRIB_BITS + ALPHA12 = C.GL_ALPHA12 + ALPHA16_SNORM = C.GL_ALPHA16_SNORM + ALPHA16 = C.GL_ALPHA16 + ALPHA4 = C.GL_ALPHA4 + ALPHA8_SNORM = C.GL_ALPHA8_SNORM + ALPHA8 = C.GL_ALPHA8 + ALPHA_BIAS = C.GL_ALPHA_BIAS + ALPHA_BITS = C.GL_ALPHA_BITS + ALPHA_INTEGER = C.GL_ALPHA_INTEGER + ALPHA_SCALE = C.GL_ALPHA_SCALE + ALPHA_SNORM = C.GL_ALPHA_SNORM + ALPHA_TEST_FUNC = C.GL_ALPHA_TEST_FUNC + ALPHA_TEST_REF = C.GL_ALPHA_TEST_REF + ALPHA_TEST = C.GL_ALPHA_TEST + ALPHA = C.GL_ALPHA + ALREADY_SIGNALED = C.GL_ALREADY_SIGNALED + ALWAYS = C.GL_ALWAYS + AMBIENT_AND_DIFFUSE = C.GL_AMBIENT_AND_DIFFUSE + AMBIENT = C.GL_AMBIENT + AND_INVERTED = C.GL_AND_INVERTED + AND_REVERSE = C.GL_AND_REVERSE + AND = C.GL_AND + ANY_SAMPLES_PASSED = C.GL_ANY_SAMPLES_PASSED + ARRAY_BUFFER_BINDING = C.GL_ARRAY_BUFFER_BINDING + ARRAY_BUFFER = C.GL_ARRAY_BUFFER + ATTACHED_SHADERS = C.GL_ATTACHED_SHADERS + ATTRIB_STACK_DEPTH = C.GL_ATTRIB_STACK_DEPTH + AUTO_NORMAL = C.GL_AUTO_NORMAL + AUX0 = C.GL_AUX0 + AUX1 = C.GL_AUX1 + AUX2 = C.GL_AUX2 + AUX3 = C.GL_AUX3 + AUX_BUFFERS = C.GL_AUX_BUFFERS + BACK_LEFT = C.GL_BACK_LEFT + BACK_RIGHT = C.GL_BACK_RIGHT + BACK = C.GL_BACK + BGRA_INTEGER = C.GL_BGRA_INTEGER + BGRA = C.GL_BGRA + BGR_INTEGER = C.GL_BGR_INTEGER + BGR = C.GL_BGR + BITMAP_TOKEN = C.GL_BITMAP_TOKEN + BITMAP = C.GL_BITMAP + BLEND_COLOR = C.GL_BLEND_COLOR + BLEND_DST_ALPHA = C.GL_BLEND_DST_ALPHA + BLEND_DST_RGB = C.GL_BLEND_DST_RGB + BLEND_DST = C.GL_BLEND_DST + BLEND_EQUATION_ALPHA = C.GL_BLEND_EQUATION_ALPHA + BLEND_EQUATION_RGB = C.GL_BLEND_EQUATION_RGB + BLEND_EQUATION = C.GL_BLEND_EQUATION + BLEND_SRC_ALPHA = C.GL_BLEND_SRC_ALPHA + BLEND_SRC_RGB = C.GL_BLEND_SRC_RGB + BLEND_SRC = C.GL_BLEND_SRC + BLEND = C.GL_BLEND + BLUE_BIAS = C.GL_BLUE_BIAS + BLUE_BITS = C.GL_BLUE_BITS + BLUE_INTEGER = C.GL_BLUE_INTEGER + BLUE_SCALE = C.GL_BLUE_SCALE + BLUE = C.GL_BLUE + BOOL_VEC2 = C.GL_BOOL_VEC2 + BOOL_VEC3 = C.GL_BOOL_VEC3 + BOOL_VEC4 = C.GL_BOOL_VEC4 + BOOL = C.GL_BOOL + BUFFER_ACCESS_FLAGS = C.GL_BUFFER_ACCESS_FLAGS + BUFFER_ACCESS = C.GL_BUFFER_ACCESS + BUFFER_MAP_LENGTH = C.GL_BUFFER_MAP_LENGTH + BUFFER_MAP_OFFSET = C.GL_BUFFER_MAP_OFFSET + BUFFER_MAPPED = C.GL_BUFFER_MAPPED + BUFFER_MAP_POINTER = C.GL_BUFFER_MAP_POINTER + BUFFER_SIZE = C.GL_BUFFER_SIZE + BUFFER_USAGE = C.GL_BUFFER_USAGE + BYTE = C.GL_BYTE + C3F_V3F = C.GL_C3F_V3F + C4F_N3F_V3F = C.GL_C4F_N3F_V3F + C4UB_V2F = C.GL_C4UB_V2F + C4UB_V3F = C.GL_C4UB_V3F + CCW = C.GL_CCW + CLAMP_FRAGMENT_COLOR = C.GL_CLAMP_FRAGMENT_COLOR + CLAMP_READ_COLOR = C.GL_CLAMP_READ_COLOR + CLAMP_TO_BORDER = C.GL_CLAMP_TO_BORDER + CLAMP_TO_EDGE = C.GL_CLAMP_TO_EDGE + CLAMP_VERTEX_COLOR = C.GL_CLAMP_VERTEX_COLOR + CLAMP = C.GL_CLAMP + CLEAR = C.GL_CLEAR + CLIENT_ACTIVE_TEXTURE = C.GL_CLIENT_ACTIVE_TEXTURE + CLIENT_ALL_ATTRIB_BITS = C.GL_CLIENT_ALL_ATTRIB_BITS + CLIENT_ATTRIB_STACK_DEPTH = C.GL_CLIENT_ATTRIB_STACK_DEPTH + CLIENT_PIXEL_STORE_BIT = C.GL_CLIENT_PIXEL_STORE_BIT + CLIENT_VERTEX_ARRAY_BIT = C.GL_CLIENT_VERTEX_ARRAY_BIT + CLIP_DISTANCE0 = C.GL_CLIP_DISTANCE0 + CLIP_DISTANCE1 = C.GL_CLIP_DISTANCE1 + CLIP_DISTANCE2 = C.GL_CLIP_DISTANCE2 + CLIP_DISTANCE3 = C.GL_CLIP_DISTANCE3 + CLIP_DISTANCE4 = C.GL_CLIP_DISTANCE4 + CLIP_DISTANCE5 = C.GL_CLIP_DISTANCE5 + CLIP_PLANE0 = C.GL_CLIP_PLANE0 + CLIP_PLANE1 = C.GL_CLIP_PLANE1 + CLIP_PLANE2 = C.GL_CLIP_PLANE2 + CLIP_PLANE3 = C.GL_CLIP_PLANE3 + CLIP_PLANE4 = C.GL_CLIP_PLANE4 + CLIP_PLANE5 = C.GL_CLIP_PLANE5 + COEFF = C.GL_COEFF + COLOR_ARRAY_BUFFER_BINDING = C.GL_COLOR_ARRAY_BUFFER_BINDING + COLOR_ARRAY_POINTER = C.GL_COLOR_ARRAY_POINTER + COLOR_ARRAY_SIZE = C.GL_COLOR_ARRAY_SIZE + COLOR_ARRAY_STRIDE = C.GL_COLOR_ARRAY_STRIDE + COLOR_ARRAY_TYPE = C.GL_COLOR_ARRAY_TYPE + COLOR_ARRAY = C.GL_COLOR_ARRAY + COLOR_ATTACHMENT0 = C.GL_COLOR_ATTACHMENT0 + COLOR_ATTACHMENT10 = C.GL_COLOR_ATTACHMENT10 + COLOR_ATTACHMENT11 = C.GL_COLOR_ATTACHMENT11 + COLOR_ATTACHMENT12 = C.GL_COLOR_ATTACHMENT12 + COLOR_ATTACHMENT13 = C.GL_COLOR_ATTACHMENT13 + COLOR_ATTACHMENT14 = C.GL_COLOR_ATTACHMENT14 + COLOR_ATTACHMENT15 = C.GL_COLOR_ATTACHMENT15 + COLOR_ATTACHMENT1 = C.GL_COLOR_ATTACHMENT1 + COLOR_ATTACHMENT2 = C.GL_COLOR_ATTACHMENT2 + COLOR_ATTACHMENT3 = C.GL_COLOR_ATTACHMENT3 + COLOR_ATTACHMENT4 = C.GL_COLOR_ATTACHMENT4 + COLOR_ATTACHMENT5 = C.GL_COLOR_ATTACHMENT5 + COLOR_ATTACHMENT6 = C.GL_COLOR_ATTACHMENT6 + COLOR_ATTACHMENT7 = C.GL_COLOR_ATTACHMENT7 + COLOR_ATTACHMENT8 = C.GL_COLOR_ATTACHMENT8 + COLOR_ATTACHMENT9 = C.GL_COLOR_ATTACHMENT9 + COLOR_BUFFER_BIT = C.GL_COLOR_BUFFER_BIT + COLOR_CLEAR_VALUE = C.GL_COLOR_CLEAR_VALUE + COLOR_INDEXES = C.GL_COLOR_INDEXES + COLOR_INDEX = C.GL_COLOR_INDEX + COLOR_LOGIC_OP = C.GL_COLOR_LOGIC_OP + COLOR_MATERIAL_FACE = C.GL_COLOR_MATERIAL_FACE + COLOR_MATERIAL_PARAMETER = C.GL_COLOR_MATERIAL_PARAMETER + COLOR_MATERIAL = C.GL_COLOR_MATERIAL + COLOR_MATRIX_STACK_DEPTH = C.GL_COLOR_MATRIX_STACK_DEPTH + COLOR_MATRIX = C.GL_COLOR_MATRIX + COLOR_SUM = C.GL_COLOR_SUM + COLOR_TABLE_ALPHA_SIZE = C.GL_COLOR_TABLE_ALPHA_SIZE + COLOR_TABLE_BIAS = C.GL_COLOR_TABLE_BIAS + COLOR_TABLE_BLUE_SIZE = C.GL_COLOR_TABLE_BLUE_SIZE + COLOR_TABLE_FORMAT = C.GL_COLOR_TABLE_FORMAT + COLOR_TABLE_GREEN_SIZE = C.GL_COLOR_TABLE_GREEN_SIZE + COLOR_TABLE_INTENSITY_SIZE = C.GL_COLOR_TABLE_INTENSITY_SIZE + COLOR_TABLE_LUMINANCE_SIZE = C.GL_COLOR_TABLE_LUMINANCE_SIZE + COLOR_TABLE_RED_SIZE = C.GL_COLOR_TABLE_RED_SIZE + COLOR_TABLE_SCALE = C.GL_COLOR_TABLE_SCALE + COLOR_TABLE_WIDTH = C.GL_COLOR_TABLE_WIDTH + COLOR_TABLE = C.GL_COLOR_TABLE + COLOR_WRITEMASK = C.GL_COLOR_WRITEMASK + COLOR = C.GL_COLOR + COMBINE_ALPHA = C.GL_COMBINE_ALPHA + COMBINE_RGB = C.GL_COMBINE_RGB + COMBINE = C.GL_COMBINE + COMPARE_REF_TO_TEXTURE = C.GL_COMPARE_REF_TO_TEXTURE + COMPARE_R_TO_TEXTURE = C.GL_COMPARE_R_TO_TEXTURE + COMPILE_AND_EXECUTE = C.GL_COMPILE_AND_EXECUTE + COMPILE_STATUS = C.GL_COMPILE_STATUS + COMPILE = C.GL_COMPILE + COMPRESSED_ALPHA = C.GL_COMPRESSED_ALPHA + COMPRESSED_INTENSITY = C.GL_COMPRESSED_INTENSITY + COMPRESSED_LUMINANCE_ALPHA = C.GL_COMPRESSED_LUMINANCE_ALPHA + COMPRESSED_LUMINANCE = C.GL_COMPRESSED_LUMINANCE + COMPRESSED_RED_RGTC1 = C.GL_COMPRESSED_RED_RGTC1 + COMPRESSED_RED = C.GL_COMPRESSED_RED + COMPRESSED_RGBA = C.GL_COMPRESSED_RGBA + COMPRESSED_RGBA_S3TC_DXT1_EXT = C.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT + COMPRESSED_RGBA_S3TC_DXT3_EXT = C.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT + COMPRESSED_RGBA_S3TC_DXT5_EXT = C.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT + COMPRESSED_RGB = C.GL_COMPRESSED_RGB + COMPRESSED_RGB_S3TC_DXT1_EXT = C.GL_COMPRESSED_RGB_S3TC_DXT1_EXT + COMPRESSED_RG_RGTC2 = C.GL_COMPRESSED_RG_RGTC2 + COMPRESSED_RG = C.GL_COMPRESSED_RG + COMPRESSED_SIGNED_RED_RGTC1 = C.GL_COMPRESSED_SIGNED_RED_RGTC1 + COMPRESSED_SIGNED_RG_RGTC2 = C.GL_COMPRESSED_SIGNED_RG_RGTC2 + COMPRESSED_SLUMINANCE_ALPHA = C.GL_COMPRESSED_SLUMINANCE_ALPHA + COMPRESSED_SLUMINANCE = C.GL_COMPRESSED_SLUMINANCE + COMPRESSED_SRGB_ALPHA = C.GL_COMPRESSED_SRGB_ALPHA + COMPRESSED_SRGB = C.GL_COMPRESSED_SRGB + COMPRESSED_TEXTURE_FORMATS = C.GL_COMPRESSED_TEXTURE_FORMATS + CONDITION_SATISFIED = C.GL_CONDITION_SATISFIED + CONSTANT_ALPHA = C.GL_CONSTANT_ALPHA + CONSTANT_ATTENUATION = C.GL_CONSTANT_ATTENUATION + CONSTANT_BORDER = C.GL_CONSTANT_BORDER + CONSTANT_COLOR = C.GL_CONSTANT_COLOR + CONSTANT = C.GL_CONSTANT + CONTEXT_COMPATIBILITY_PROFILE_BIT = C.GL_CONTEXT_COMPATIBILITY_PROFILE_BIT + CONTEXT_CORE_PROFILE_BIT = C.GL_CONTEXT_CORE_PROFILE_BIT + CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT = C.GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT + CONTEXT_FLAGS = C.GL_CONTEXT_FLAGS + CONTEXT_PROFILE_MASK = C.GL_CONTEXT_PROFILE_MASK + CONVOLUTION_1D = C.GL_CONVOLUTION_1D + CONVOLUTION_2D = C.GL_CONVOLUTION_2D + CONVOLUTION_BORDER_COLOR = C.GL_CONVOLUTION_BORDER_COLOR + CONVOLUTION_BORDER_MODE = C.GL_CONVOLUTION_BORDER_MODE + CONVOLUTION_FILTER_BIAS = C.GL_CONVOLUTION_FILTER_BIAS + CONVOLUTION_FILTER_SCALE = C.GL_CONVOLUTION_FILTER_SCALE + CONVOLUTION_FORMAT = C.GL_CONVOLUTION_FORMAT + CONVOLUTION_HEIGHT = C.GL_CONVOLUTION_HEIGHT + CONVOLUTION_WIDTH = C.GL_CONVOLUTION_WIDTH + COORD_REPLACE = C.GL_COORD_REPLACE + COPY_INVERTED = C.GL_COPY_INVERTED + COPY_PIXEL_TOKEN = C.GL_COPY_PIXEL_TOKEN + COPY_READ_BUFFER = C.GL_COPY_READ_BUFFER + COPY_WRITE_BUFFER = C.GL_COPY_WRITE_BUFFER + COPY = C.GL_COPY + CULL_FACE_MODE = C.GL_CULL_FACE_MODE + CULL_FACE = C.GL_CULL_FACE + CURRENT_BIT = C.GL_CURRENT_BIT + CURRENT_COLOR = C.GL_CURRENT_COLOR + CURRENT_FOG_COORDINATE = C.GL_CURRENT_FOG_COORDINATE + CURRENT_FOG_COORD = C.GL_CURRENT_FOG_COORD + CURRENT_INDEX = C.GL_CURRENT_INDEX + CURRENT_NORMAL = C.GL_CURRENT_NORMAL + CURRENT_PROGRAM = C.GL_CURRENT_PROGRAM + CURRENT_QUERY = C.GL_CURRENT_QUERY + CURRENT_RASTER_COLOR = C.GL_CURRENT_RASTER_COLOR + CURRENT_RASTER_DISTANCE = C.GL_CURRENT_RASTER_DISTANCE + CURRENT_RASTER_INDEX = C.GL_CURRENT_RASTER_INDEX + CURRENT_RASTER_POSITION_VALID = C.GL_CURRENT_RASTER_POSITION_VALID + CURRENT_RASTER_POSITION = C.GL_CURRENT_RASTER_POSITION + CURRENT_RASTER_SECONDARY_COLOR = C.GL_CURRENT_RASTER_SECONDARY_COLOR + CURRENT_RASTER_TEXTURE_COORDS = C.GL_CURRENT_RASTER_TEXTURE_COORDS + CURRENT_SECONDARY_COLOR = C.GL_CURRENT_SECONDARY_COLOR + CURRENT_TEXTURE_COORDS = C.GL_CURRENT_TEXTURE_COORDS + CURRENT_VERTEX_ATTRIB = C.GL_CURRENT_VERTEX_ATTRIB + CW = C.GL_CW + DECAL = C.GL_DECAL + DECR_WRAP = C.GL_DECR_WRAP + DECR = C.GL_DECR + DEBUG_OUTPUT_SYNCHRONOUS = C.GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB + DEBUG_NEXT_LOGGED_MESSAGE_LENGTH = C.GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB + DEBUG_CALLBACK_FUNCTION = C.GL_DEBUG_CALLBACK_FUNCTION_ARB + DEBUG_CALLBACK_USER_PARAM = C.GL_DEBUG_CALLBACK_USER_PARAM_ARB + DEBUG_SOURCE_API = C.GL_DEBUG_SOURCE_API_ARB + DEBUG_SOURCE_WINDOW_SYSTEM = C.GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB + DEBUG_SOURCE_SHADER_COMPILER = C.GL_DEBUG_SOURCE_SHADER_COMPILER_ARB + DEBUG_SOURCE_THIRD_PARTY = C.GL_DEBUG_SOURCE_THIRD_PARTY_ARB + DEBUG_SOURCE_APPLICATION = C.GL_DEBUG_SOURCE_APPLICATION_ARB + DEBUG_SOURCE_OTHER = C.GL_DEBUG_SOURCE_OTHER_ARB + DEBUG_TYPE_ERROR = C.GL_DEBUG_TYPE_ERROR_ARB + DEBUG_TYPE_DEPRECATED_BEHAVIOR = C.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB + DEBUG_TYPE_UNDEFINED_BEHAVIOR = C.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB + DEBUG_TYPE_PORTABILITY = C.GL_DEBUG_TYPE_PORTABILITY_ARB + DEBUG_TYPE_PERFORMANCE = C.GL_DEBUG_TYPE_PERFORMANCE_ARB + DEBUG_TYPE_OTHER = C.GL_DEBUG_TYPE_OTHER_ARB + DEBUG_LOGGED_MESSAGES = C.GL_DEBUG_LOGGED_MESSAGES_ARB + DEBUG_SEVERITY_HIGH = C.GL_DEBUG_SEVERITY_HIGH_ARB + DEBUG_SEVERITY_MEDIUM = C.GL_DEBUG_SEVERITY_MEDIUM_ARB + DEBUG_SEVERITY_LOW = C.GL_DEBUG_SEVERITY_LOW_ARB + DELETE_STATUS = C.GL_DELETE_STATUS + DEPTH24_STENCIL8 = C.GL_DEPTH24_STENCIL8 + DEPTH32F_STENCIL8 = C.GL_DEPTH32F_STENCIL8 + DEPTH_ATTACHMENT = C.GL_DEPTH_ATTACHMENT + DEPTH_BIAS = C.GL_DEPTH_BIAS + DEPTH_BITS = C.GL_DEPTH_BITS + DEPTH_BUFFER_BIT = C.GL_DEPTH_BUFFER_BIT + DEPTH_BUFFER = C.GL_DEPTH_BUFFER + DEPTH_CLAMP = C.GL_DEPTH_CLAMP + DEPTH_CLEAR_VALUE = C.GL_DEPTH_CLEAR_VALUE + DEPTH_COMPONENT16 = C.GL_DEPTH_COMPONENT16 + DEPTH_COMPONENT24 = C.GL_DEPTH_COMPONENT24 + DEPTH_COMPONENT32F = C.GL_DEPTH_COMPONENT32F + DEPTH_COMPONENT32 = C.GL_DEPTH_COMPONENT32 + DEPTH_COMPONENT = C.GL_DEPTH_COMPONENT + DEPTH_FUNC = C.GL_DEPTH_FUNC + DEPTH_RANGE = C.GL_DEPTH_RANGE + DEPTH_SCALE = C.GL_DEPTH_SCALE + DEPTH_STENCIL_ATTACHMENT = C.GL_DEPTH_STENCIL_ATTACHMENT + DEPTH_STENCIL = C.GL_DEPTH_STENCIL + DEPTH_TEST = C.GL_DEPTH_TEST + DEPTH_TEXTURE_MODE = C.GL_DEPTH_TEXTURE_MODE + DEPTH_WRITEMASK = C.GL_DEPTH_WRITEMASK + DEPTH = C.GL_DEPTH + DIFFUSE = C.GL_DIFFUSE + DITHER = C.GL_DITHER + DOMAIN = C.GL_DOMAIN + DONT_CARE = C.GL_DONT_CARE + DOT3_RGBA = C.GL_DOT3_RGBA + DOT3_RGB = C.GL_DOT3_RGB + DOUBLEBUFFER = C.GL_DOUBLEBUFFER + DOUBLE = C.GL_DOUBLE + DRAW_BUFFER0 = C.GL_DRAW_BUFFER0 + DRAW_BUFFER10 = C.GL_DRAW_BUFFER10 + DRAW_BUFFER11 = C.GL_DRAW_BUFFER11 + DRAW_BUFFER12 = C.GL_DRAW_BUFFER12 + DRAW_BUFFER13 = C.GL_DRAW_BUFFER13 + DRAW_BUFFER14 = C.GL_DRAW_BUFFER14 + DRAW_BUFFER15 = C.GL_DRAW_BUFFER15 + DRAW_BUFFER1 = C.GL_DRAW_BUFFER1 + DRAW_BUFFER2 = C.GL_DRAW_BUFFER2 + DRAW_BUFFER3 = C.GL_DRAW_BUFFER3 + DRAW_BUFFER4 = C.GL_DRAW_BUFFER4 + DRAW_BUFFER5 = C.GL_DRAW_BUFFER5 + DRAW_BUFFER6 = C.GL_DRAW_BUFFER6 + DRAW_BUFFER7 = C.GL_DRAW_BUFFER7 + DRAW_BUFFER8 = C.GL_DRAW_BUFFER8 + DRAW_BUFFER9 = C.GL_DRAW_BUFFER9 + DRAW_BUFFER = C.GL_DRAW_BUFFER + DRAW_FRAMEBUFFER_BINDING = C.GL_DRAW_FRAMEBUFFER_BINDING + DRAW_FRAMEBUFFER = C.GL_DRAW_FRAMEBUFFER + DRAW_PIXEL_TOKEN = C.GL_DRAW_PIXEL_TOKEN + DST_ALPHA = C.GL_DST_ALPHA + DST_COLOR = C.GL_DST_COLOR + DYNAMIC_COPY = C.GL_DYNAMIC_COPY + DYNAMIC_DRAW = C.GL_DYNAMIC_DRAW + DYNAMIC_READ = C.GL_DYNAMIC_READ + EDGE_FLAG_ARRAY_BUFFER_BINDING = C.GL_EDGE_FLAG_ARRAY_BUFFER_BINDING + EDGE_FLAG_ARRAY_POINTER = C.GL_EDGE_FLAG_ARRAY_POINTER + EDGE_FLAG_ARRAY_STRIDE = C.GL_EDGE_FLAG_ARRAY_STRIDE + EDGE_FLAG_ARRAY = C.GL_EDGE_FLAG_ARRAY + EDGE_FLAG = C.GL_EDGE_FLAG + ELEMENT_ARRAY_BUFFER_BINDING = C.GL_ELEMENT_ARRAY_BUFFER_BINDING + ELEMENT_ARRAY_BUFFER = C.GL_ELEMENT_ARRAY_BUFFER + EMISSION = C.GL_EMISSION + ENABLE_BIT = C.GL_ENABLE_BIT + EQUAL = C.GL_EQUAL + EQUIV = C.GL_EQUIV + EVAL_BIT = C.GL_EVAL_BIT + EXP2 = C.GL_EXP2 + EXP = C.GL_EXP + EXTENSIONS = C.GL_EXTENSIONS + EYE_LINEAR = C.GL_EYE_LINEAR + EYE_PLANE = C.GL_EYE_PLANE + FALSE = C.GL_FALSE + FASTEST = C.GL_FASTEST + FEEDBACK_BUFFER_POINTER = C.GL_FEEDBACK_BUFFER_POINTER + FEEDBACK_BUFFER_SIZE = C.GL_FEEDBACK_BUFFER_SIZE + FEEDBACK_BUFFER_TYPE = C.GL_FEEDBACK_BUFFER_TYPE + FEEDBACK = C.GL_FEEDBACK + FILL = C.GL_FILL + FIRST_VERTEX_CONVENTION = C.GL_FIRST_VERTEX_CONVENTION + FIXED_ONLY = C.GL_FIXED_ONLY + FLAT = C.GL_FLAT + FLOAT_32_UNSIGNED_INT_24_8_REV = C.GL_FLOAT_32_UNSIGNED_INT_24_8_REV + FLOAT_MAT2x3 = C.GL_FLOAT_MAT2x3 + FLOAT_MAT2x4 = C.GL_FLOAT_MAT2x4 + FLOAT_MAT2 = C.GL_FLOAT_MAT2 + FLOAT_MAT3x2 = C.GL_FLOAT_MAT3x2 + FLOAT_MAT3x4 = C.GL_FLOAT_MAT3x4 + FLOAT_MAT3 = C.GL_FLOAT_MAT3 + FLOAT_MAT4x2 = C.GL_FLOAT_MAT4x2 + FLOAT_MAT4x3 = C.GL_FLOAT_MAT4x3 + FLOAT_MAT4 = C.GL_FLOAT_MAT4 + FLOAT_VEC2 = C.GL_FLOAT_VEC2 + FLOAT_VEC3 = C.GL_FLOAT_VEC3 + FLOAT_VEC4 = C.GL_FLOAT_VEC4 + FLOAT = C.GL_FLOAT + FOG_BIT = C.GL_FOG_BIT + FOG_COLOR = C.GL_FOG_COLOR + FOG_COORD_ARRAY_BUFFER_BINDING = C.GL_FOG_COORD_ARRAY_BUFFER_BINDING + FOG_COORD_ARRAY_POINTER = C.GL_FOG_COORD_ARRAY_POINTER + FOG_COORD_ARRAY_STRIDE = C.GL_FOG_COORD_ARRAY_STRIDE + FOG_COORD_ARRAY_TYPE = C.GL_FOG_COORD_ARRAY_TYPE + FOG_COORD_ARRAY = C.GL_FOG_COORD_ARRAY + FOG_COORDINATE_ARRAY_BUFFER_BINDING = C.GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING + FOG_COORDINATE_ARRAY_POINTER = C.GL_FOG_COORDINATE_ARRAY_POINTER + FOG_COORDINATE_ARRAY_STRIDE = C.GL_FOG_COORDINATE_ARRAY_STRIDE + FOG_COORDINATE_ARRAY_TYPE = C.GL_FOG_COORDINATE_ARRAY_TYPE + FOG_COORDINATE_ARRAY = C.GL_FOG_COORDINATE_ARRAY + FOG_COORDINATE_SOURCE = C.GL_FOG_COORDINATE_SOURCE + FOG_COORDINATE = C.GL_FOG_COORDINATE + FOG_COORD_SRC = C.GL_FOG_COORD_SRC + FOG_COORD = C.GL_FOG_COORD + FOG_DENSITY = C.GL_FOG_DENSITY + FOG_END = C.GL_FOG_END + FOG_HINT = C.GL_FOG_HINT + FOG_INDEX = C.GL_FOG_INDEX + FOG_MODE = C.GL_FOG_MODE + FOG_START = C.GL_FOG_START + FOG = C.GL_FOG + FRAGMENT_DEPTH = C.GL_FRAGMENT_DEPTH + FRAGMENT_SHADER_DERIVATIVE_HINT = C.GL_FRAGMENT_SHADER_DERIVATIVE_HINT + FRAGMENT_SHADER = C.GL_FRAGMENT_SHADER + FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = C.GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE + FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = C.GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE + FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = C.GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING + FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = C.GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE + FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = C.GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE + FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = C.GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE + FRAMEBUFFER_ATTACHMENT_LAYERED = C.GL_FRAMEBUFFER_ATTACHMENT_LAYERED + FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = C.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME + FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = C.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE + FRAMEBUFFER_ATTACHMENT_RED_SIZE = C.GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE + FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = C.GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE + FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = C.GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE + FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = C.GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER + FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = C.GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL + FRAMEBUFFER_BINDING = C.GL_FRAMEBUFFER_BINDING + FRAMEBUFFER_COMPLETE = C.GL_FRAMEBUFFER_COMPLETE + FRAMEBUFFER_DEFAULT = C.GL_FRAMEBUFFER_DEFAULT + FRAMEBUFFER_INCOMPLETE_ATTACHMENT = C.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT + FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = C.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER + FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = C.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS + FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = C.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = C.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE + FRAMEBUFFER_INCOMPLETE_READ_BUFFER = C.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER + FRAMEBUFFER_SRGB = C.GL_FRAMEBUFFER_SRGB + FRAMEBUFFER_UNDEFINED = C.GL_FRAMEBUFFER_UNDEFINED + FRAMEBUFFER_UNSUPPORTED = C.GL_FRAMEBUFFER_UNSUPPORTED + FRAMEBUFFER = C.GL_FRAMEBUFFER + FRONT_AND_BACK = C.GL_FRONT_AND_BACK + FRONT_FACE = C.GL_FRONT_FACE + FRONT_LEFT = C.GL_FRONT_LEFT + FRONT_RIGHT = C.GL_FRONT_RIGHT + FRONT = C.GL_FRONT + FUNC_ADD = C.GL_FUNC_ADD + FUNC_REVERSE_SUBTRACT = C.GL_FUNC_REVERSE_SUBTRACT + FUNC_SUBTRACT = C.GL_FUNC_SUBTRACT + GENERATE_MIPMAP_HINT = C.GL_GENERATE_MIPMAP_HINT + GENERATE_MIPMAP = C.GL_GENERATE_MIPMAP + GEOMETRY_INPUT_TYPE = C.GL_GEOMETRY_INPUT_TYPE + GEOMETRY_OUTPUT_TYPE = C.GL_GEOMETRY_OUTPUT_TYPE + GEOMETRY_SHADER = C.GL_GEOMETRY_SHADER + GEOMETRY_VERTICES_OUT = C.GL_GEOMETRY_VERTICES_OUT + GEQUAL = C.GL_GEQUAL + GREATER = C.GL_GREATER + GREEN_BIAS = C.GL_GREEN_BIAS + GREEN_BITS = C.GL_GREEN_BITS + GREEN_INTEGER = C.GL_GREEN_INTEGER + GREEN_SCALE = C.GL_GREEN_SCALE + GREEN = C.GL_GREEN + HALF_FLOAT = C.GL_HALF_FLOAT + HINT_BIT = C.GL_HINT_BIT + HISTOGRAM_ALPHA_SIZE = C.GL_HISTOGRAM_ALPHA_SIZE + HISTOGRAM_BLUE_SIZE = C.GL_HISTOGRAM_BLUE_SIZE + HISTOGRAM_FORMAT = C.GL_HISTOGRAM_FORMAT + HISTOGRAM_GREEN_SIZE = C.GL_HISTOGRAM_GREEN_SIZE + HISTOGRAM_LUMINANCE_SIZE = C.GL_HISTOGRAM_LUMINANCE_SIZE + HISTOGRAM_RED_SIZE = C.GL_HISTOGRAM_RED_SIZE + HISTOGRAM_SINK = C.GL_HISTOGRAM_SINK + HISTOGRAM_WIDTH = C.GL_HISTOGRAM_WIDTH + HISTOGRAM = C.GL_HISTOGRAM + INCR_WRAP = C.GL_INCR_WRAP + INCR = C.GL_INCR + INDEX_ARRAY_BUFFER_BINDING = C.GL_INDEX_ARRAY_BUFFER_BINDING + INDEX_ARRAY_POINTER = C.GL_INDEX_ARRAY_POINTER + INDEX_ARRAY_STRIDE = C.GL_INDEX_ARRAY_STRIDE + INDEX_ARRAY_TYPE = C.GL_INDEX_ARRAY_TYPE + INDEX_ARRAY = C.GL_INDEX_ARRAY + INDEX_BITS = C.GL_INDEX_BITS + INDEX_CLEAR_VALUE = C.GL_INDEX_CLEAR_VALUE + INDEX_LOGIC_OP = C.GL_INDEX_LOGIC_OP + INDEX_MODE = C.GL_INDEX_MODE + INDEX_OFFSET = C.GL_INDEX_OFFSET + INDEX_SHIFT = C.GL_INDEX_SHIFT + INDEX_WRITEMASK = C.GL_INDEX_WRITEMASK + INDEX = C.GL_INDEX + INFO_LOG_LENGTH = C.GL_INFO_LOG_LENGTH + INTENSITY12 = C.GL_INTENSITY12 + INTENSITY16_SNORM = C.GL_INTENSITY16_SNORM + INTENSITY16 = C.GL_INTENSITY16 + INTENSITY4 = C.GL_INTENSITY4 + INTENSITY8_SNORM = C.GL_INTENSITY8_SNORM + INTENSITY8 = C.GL_INTENSITY8 + INTENSITY_SNORM = C.GL_INTENSITY_SNORM + INTENSITY = C.GL_INTENSITY + INTERLEAVED_ATTRIBS = C.GL_INTERLEAVED_ATTRIBS + INTERPOLATE = C.GL_INTERPOLATE + INT_SAMPLER_1D_ARRAY = C.GL_INT_SAMPLER_1D_ARRAY + INT_SAMPLER_1D = C.GL_INT_SAMPLER_1D + INT_SAMPLER_2D_ARRAY = C.GL_INT_SAMPLER_2D_ARRAY + INT_SAMPLER_2D_MULTISAMPLE_ARRAY = C.GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY + INT_SAMPLER_2D_MULTISAMPLE = C.GL_INT_SAMPLER_2D_MULTISAMPLE + INT_SAMPLER_2D_RECT = C.GL_INT_SAMPLER_2D_RECT + INT_SAMPLER_2D = C.GL_INT_SAMPLER_2D + INT_SAMPLER_3D = C.GL_INT_SAMPLER_3D + INT_SAMPLER_BUFFER = C.GL_INT_SAMPLER_BUFFER + INT_SAMPLER_CUBE_MAP_ARRAY = C.GL_INT_SAMPLER_CUBE_MAP_ARRAY + INT_SAMPLER_CUBE = C.GL_INT_SAMPLER_CUBE + INT_VEC2 = C.GL_INT_VEC2 + INT_VEC3 = C.GL_INT_VEC3 + INT_VEC4 = C.GL_INT_VEC4 + INT = C.GL_INT + INVALID_ENUM = C.GL_INVALID_ENUM + INVALID_FRAMEBUFFER_OPERATION = C.GL_INVALID_FRAMEBUFFER_OPERATION + INVALID_INDEX = C.GL_INVALID_INDEX + INVALID_OPERATION = C.GL_INVALID_OPERATION + INVALID_VALUE = C.GL_INVALID_VALUE + INVERTED_SCREEN_W_REND = C.GL_INVERTED_SCREEN_W_REND + INVERT = C.GL_INVERT + KEEP = C.GL_KEEP + LAST_VERTEX_CONVENTION = C.GL_LAST_VERTEX_CONVENTION + LEFT = C.GL_LEFT + LEQUAL = C.GL_LEQUAL + LESS = C.GL_LESS + LIGHT0 = C.GL_LIGHT0 + LIGHT1 = C.GL_LIGHT1 + LIGHT2 = C.GL_LIGHT2 + LIGHT3 = C.GL_LIGHT3 + LIGHT4 = C.GL_LIGHT4 + LIGHT5 = C.GL_LIGHT5 + LIGHT6 = C.GL_LIGHT6 + LIGHT7 = C.GL_LIGHT7 + LIGHTING_BIT = C.GL_LIGHTING_BIT + LIGHTING = C.GL_LIGHTING + LIGHT_MODEL_AMBIENT = C.GL_LIGHT_MODEL_AMBIENT + LIGHT_MODEL_COLOR_CONTROL = C.GL_LIGHT_MODEL_COLOR_CONTROL + LIGHT_MODEL_LOCAL_VIEWER = C.GL_LIGHT_MODEL_LOCAL_VIEWER + LIGHT_MODEL_TWO_SIDE = C.GL_LIGHT_MODEL_TWO_SIDE + LINEAR_ATTENUATION = C.GL_LINEAR_ATTENUATION + LINEAR_MIPMAP_LINEAR = C.GL_LINEAR_MIPMAP_LINEAR + LINEAR_MIPMAP_NEAREST = C.GL_LINEAR_MIPMAP_NEAREST + LINEAR = C.GL_LINEAR + LINE_BIT = C.GL_LINE_BIT + LINE_LOOP = C.GL_LINE_LOOP + LINE_RESET_TOKEN = C.GL_LINE_RESET_TOKEN + LINES_ADJACENCY = C.GL_LINES_ADJACENCY + LINE_SMOOTH_HINT = C.GL_LINE_SMOOTH_HINT + LINE_SMOOTH = C.GL_LINE_SMOOTH + LINE_STIPPLE_PATTERN = C.GL_LINE_STIPPLE_PATTERN + LINE_STIPPLE_REPEAT = C.GL_LINE_STIPPLE_REPEAT + LINE_STIPPLE = C.GL_LINE_STIPPLE + LINE_STRIP_ADJACENCY = C.GL_LINE_STRIP_ADJACENCY + LINE_STRIP = C.GL_LINE_STRIP + LINES = C.GL_LINES + LINE_TOKEN = C.GL_LINE_TOKEN + LINE_WIDTH_GRANULARITY = C.GL_LINE_WIDTH_GRANULARITY + LINE_WIDTH_RANGE = C.GL_LINE_WIDTH_RANGE + LINE_WIDTH = C.GL_LINE_WIDTH + LINE = C.GL_LINE + LINK_STATUS = C.GL_LINK_STATUS + LIST_BASE = C.GL_LIST_BASE + LIST_BIT = C.GL_LIST_BIT + LIST_INDEX = C.GL_LIST_INDEX + LIST_MODE = C.GL_LIST_MODE + LOAD = C.GL_LOAD + LOGIC_OP_MODE = C.GL_LOGIC_OP_MODE + LOGIC_OP = C.GL_LOGIC_OP + LOWER_LEFT = C.GL_LOWER_LEFT + LUMINANCE12_ALPHA12 = C.GL_LUMINANCE12_ALPHA12 + LUMINANCE12_ALPHA4 = C.GL_LUMINANCE12_ALPHA4 + LUMINANCE12 = C.GL_LUMINANCE12 + LUMINANCE16_ALPHA16_SNORM = C.GL_LUMINANCE16_ALPHA16_SNORM + LUMINANCE16_ALPHA16 = C.GL_LUMINANCE16_ALPHA16 + LUMINANCE16_SNORM = C.GL_LUMINANCE16_SNORM + LUMINANCE16 = C.GL_LUMINANCE16 + LUMINANCE4_ALPHA4 = C.GL_LUMINANCE4_ALPHA4 + LUMINANCE4 = C.GL_LUMINANCE4 + LUMINANCE6_ALPHA2 = C.GL_LUMINANCE6_ALPHA2 + LUMINANCE8_ALPHA8_SNORM = C.GL_LUMINANCE8_ALPHA8_SNORM + LUMINANCE8_ALPHA8 = C.GL_LUMINANCE8_ALPHA8 + LUMINANCE8_SNORM = C.GL_LUMINANCE8_SNORM + LUMINANCE8 = C.GL_LUMINANCE8 + LUMINANCE_ALPHA_SNORM = C.GL_LUMINANCE_ALPHA_SNORM + LUMINANCE_ALPHA = C.GL_LUMINANCE_ALPHA + LUMINANCE_SNORM = C.GL_LUMINANCE_SNORM + LUMINANCE = C.GL_LUMINANCE + MAJOR_VERSION = C.GL_MAJOR_VERSION + MAP1_COLOR_4 = C.GL_MAP1_COLOR_4 + MAP1_GRID_DOMAIN = C.GL_MAP1_GRID_DOMAIN + MAP1_GRID_SEGMENTS = C.GL_MAP1_GRID_SEGMENTS + MAP1_INDEX = C.GL_MAP1_INDEX + MAP1_NORMAL = C.GL_MAP1_NORMAL + MAP1_TEXTURE_COORD_1 = C.GL_MAP1_TEXTURE_COORD_1 + MAP1_TEXTURE_COORD_2 = C.GL_MAP1_TEXTURE_COORD_2 + MAP1_TEXTURE_COORD_3 = C.GL_MAP1_TEXTURE_COORD_3 + MAP1_TEXTURE_COORD_4 = C.GL_MAP1_TEXTURE_COORD_4 + MAP1_VERTEX_3 = C.GL_MAP1_VERTEX_3 + MAP1_VERTEX_4 = C.GL_MAP1_VERTEX_4 + MAP2_COLOR_4 = C.GL_MAP2_COLOR_4 + MAP2_GRID_DOMAIN = C.GL_MAP2_GRID_DOMAIN + MAP2_GRID_SEGMENTS = C.GL_MAP2_GRID_SEGMENTS + MAP2_INDEX = C.GL_MAP2_INDEX + MAP2_NORMAL = C.GL_MAP2_NORMAL + MAP2_TEXTURE_COORD_1 = C.GL_MAP2_TEXTURE_COORD_1 + MAP2_TEXTURE_COORD_2 = C.GL_MAP2_TEXTURE_COORD_2 + MAP2_TEXTURE_COORD_3 = C.GL_MAP2_TEXTURE_COORD_3 + MAP2_TEXTURE_COORD_4 = C.GL_MAP2_TEXTURE_COORD_4 + MAP2_VERTEX_3 = C.GL_MAP2_VERTEX_3 + MAP2_VERTEX_4 = C.GL_MAP2_VERTEX_4 + MAP_COLOR = C.GL_MAP_COLOR + MAP_FLUSH_EXPLICIT_BIT = C.GL_MAP_FLUSH_EXPLICIT_BIT + MAP_INVALIDATE_BUFFER_BIT = C.GL_MAP_INVALIDATE_BUFFER_BIT + MAP_INVALIDATE_RANGE_BIT = C.GL_MAP_INVALIDATE_RANGE_BIT + MAP_READ_BIT = C.GL_MAP_READ_BIT + MAP_STENCIL = C.GL_MAP_STENCIL + MAP_UNSYNCHRONIZED_BIT = C.GL_MAP_UNSYNCHRONIZED_BIT + MAP_WRITE_BIT = C.GL_MAP_WRITE_BIT + MATRIX_MODE = C.GL_MATRIX_MODE + MAX_3D_TEXTURE_SIZE = C.GL_MAX_3D_TEXTURE_SIZE + MAX_ARRAY_TEXTURE_LAYERS = C.GL_MAX_ARRAY_TEXTURE_LAYERS + MAX_ATTRIB_STACK_DEPTH = C.GL_MAX_ATTRIB_STACK_DEPTH + MAX_CLIENT_ATTRIB_STACK_DEPTH = C.GL_MAX_CLIENT_ATTRIB_STACK_DEPTH + MAX_CLIP_DISTANCES = C.GL_MAX_CLIP_DISTANCES + MAX_CLIP_PLANES = C.GL_MAX_CLIP_PLANES + MAX_COLOR_ATTACHMENTS = C.GL_MAX_COLOR_ATTACHMENTS + MAX_COLOR_MATRIX_STACK_DEPTH = C.GL_MAX_COLOR_MATRIX_STACK_DEPTH + MAX_COLOR_TEXTURE_SAMPLES = C.GL_MAX_COLOR_TEXTURE_SAMPLES + MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = C.GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS + MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS = C.GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS + MAX_COMBINED_TEXTURE_IMAGE_UNITS = C.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS + MAX_COMBINED_UNIFORM_BLOCKS = C.GL_MAX_COMBINED_UNIFORM_BLOCKS + MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = C.GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS + MAX_CONVOLUTION_HEIGHT = C.GL_MAX_CONVOLUTION_HEIGHT + MAX_CONVOLUTION_WIDTH = C.GL_MAX_CONVOLUTION_WIDTH + MAX_CUBE_MAP_TEXTURE_SIZE = C.GL_MAX_CUBE_MAP_TEXTURE_SIZE + MAX_DEBUG_LOGGED_MESSAGES = C.GL_MAX_DEBUG_LOGGED_MESSAGES_ARB + MAX_DEBUG_MESSAGE_LENGTH = C.GL_MAX_DEBUG_MESSAGE_LENGTH_ARB + MAX_DEPTH_TEXTURE_SAMPLES = C.GL_MAX_DEPTH_TEXTURE_SAMPLES + MAX_DRAW_BUFFERS = C.GL_MAX_DRAW_BUFFERS + MAX_ELEMENTS_INDICES = C.GL_MAX_ELEMENTS_INDICES + MAX_ELEMENTS_VERTICES = C.GL_MAX_ELEMENTS_VERTICES + MAX_EVAL_ORDER = C.GL_MAX_EVAL_ORDER + MAX_FRAGMENT_INPUT_COMPONENTS = C.GL_MAX_FRAGMENT_INPUT_COMPONENTS + MAX_FRAGMENT_UNIFORM_BLOCKS = C.GL_MAX_FRAGMENT_UNIFORM_BLOCKS + MAX_FRAGMENT_UNIFORM_COMPONENTS = C.GL_MAX_FRAGMENT_UNIFORM_COMPONENTS + MAX_GEOMETRY_INPUT_COMPONENTS = C.GL_MAX_GEOMETRY_INPUT_COMPONENTS + MAX_GEOMETRY_OUTPUT_COMPONENTS = C.GL_MAX_GEOMETRY_OUTPUT_COMPONENTS + MAX_GEOMETRY_OUTPUT_VERTICES = C.GL_MAX_GEOMETRY_OUTPUT_VERTICES + MAX_GEOMETRY_TEXTURE_IMAGE_UNITS = C.GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS + MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = C.GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS + MAX_GEOMETRY_UNIFORM_BLOCKS = C.GL_MAX_GEOMETRY_UNIFORM_BLOCKS + MAX_GEOMETRY_UNIFORM_COMPONENTS = C.GL_MAX_GEOMETRY_UNIFORM_COMPONENTS + MAX_INTEGER_SAMPLES = C.GL_MAX_INTEGER_SAMPLES + MAX_LIGHTS = C.GL_MAX_LIGHTS + MAX_LIST_NESTING = C.GL_MAX_LIST_NESTING + MAX_MODELVIEW_STACK_DEPTH = C.GL_MAX_MODELVIEW_STACK_DEPTH + MAX_NAME_STACK_DEPTH = C.GL_MAX_NAME_STACK_DEPTH + MAX_PIXEL_MAP_TABLE = C.GL_MAX_PIXEL_MAP_TABLE + MAX_PROGRAM_TEXEL_OFFSET = C.GL_MAX_PROGRAM_TEXEL_OFFSET + MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS = C.GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS + MAX_PROGRAM_TEXTURE_GATHER_OFFSET = C.GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET + MAX_PROJECTION_STACK_DEPTH = C.GL_MAX_PROJECTION_STACK_DEPTH + MAX_RECTANGLE_TEXTURE_SIZE = C.GL_MAX_RECTANGLE_TEXTURE_SIZE + MAX_RENDERBUFFER_SIZE = C.GL_MAX_RENDERBUFFER_SIZE + MAX_SAMPLE_MASK_WORDS = C.GL_MAX_SAMPLE_MASK_WORDS + MAX_SAMPLES = C.GL_MAX_SAMPLES + MAX_SERVER_WAIT_TIMEOUT = C.GL_MAX_SERVER_WAIT_TIMEOUT + MAX_TEXTURE_BUFFER_SIZE = C.GL_MAX_TEXTURE_BUFFER_SIZE + MAX_TEXTURE_COORDS = C.GL_MAX_TEXTURE_COORDS + MAX_TEXTURE_IMAGE_UNITS = C.GL_MAX_TEXTURE_IMAGE_UNITS + MAX_TEXTURE_LOD_BIAS = C.GL_MAX_TEXTURE_LOD_BIAS + MAX_TEXTURE_SIZE = C.GL_MAX_TEXTURE_SIZE + MAX_TEXTURE_STACK_DEPTH = C.GL_MAX_TEXTURE_STACK_DEPTH + MAX_TEXTURE_UNITS = C.GL_MAX_TEXTURE_UNITS + MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = C.GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS + MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = C.GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS + MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = C.GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS + MAX_UNIFORM_BLOCK_SIZE = C.GL_MAX_UNIFORM_BLOCK_SIZE + MAX_UNIFORM_BUFFER_BINDINGS = C.GL_MAX_UNIFORM_BUFFER_BINDINGS + MAX_VARYING_COMPONENTS = C.GL_MAX_VARYING_COMPONENTS + MAX_VARYING_FLOATS = C.GL_MAX_VARYING_FLOATS + MAX_VERTEX_ATTRIBS = C.GL_MAX_VERTEX_ATTRIBS + MAX_VERTEX_OUTPUT_COMPONENTS = C.GL_MAX_VERTEX_OUTPUT_COMPONENTS + MAX_VERTEX_TEXTURE_IMAGE_UNITS = C.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_UNIFORM_BLOCKS = C.GL_MAX_VERTEX_UNIFORM_BLOCKS + MAX_VERTEX_UNIFORM_COMPONENTS = C.GL_MAX_VERTEX_UNIFORM_COMPONENTS + MAX_VIEWPORT_DIMS = C.GL_MAX_VIEWPORT_DIMS + MAX = C.GL_MAX + MINMAX_FORMAT = C.GL_MINMAX_FORMAT + MINMAX_SINK = C.GL_MINMAX_SINK + MINMAX = C.GL_MINMAX + MINOR_VERSION = C.GL_MINOR_VERSION + MIN_PROGRAM_TEXEL_OFFSET = C.GL_MIN_PROGRAM_TEXEL_OFFSET + MIN_PROGRAM_TEXTURE_GATHER_OFFSET = C.GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET + MIN_SAMPLE_SHADING_VALUE = C.GL_MIN_SAMPLE_SHADING_VALUE + MIN = C.GL_MIN + MIRRORED_REPEAT = C.GL_MIRRORED_REPEAT + MODELVIEW_MATRIX = C.GL_MODELVIEW_MATRIX + MODELVIEW_STACK_DEPTH = C.GL_MODELVIEW_STACK_DEPTH + MODELVIEW = C.GL_MODELVIEW + MODULATE = C.GL_MODULATE + MULTISAMPLE_BIT = C.GL_MULTISAMPLE_BIT + MULTISAMPLE = C.GL_MULTISAMPLE + MULT = C.GL_MULT + N3F_V3F = C.GL_N3F_V3F + NAME_STACK_DEPTH = C.GL_NAME_STACK_DEPTH + NAND = C.GL_NAND + NEAREST_MIPMAP_LINEAR = C.GL_NEAREST_MIPMAP_LINEAR + NEAREST_MIPMAP_NEAREST = C.GL_NEAREST_MIPMAP_NEAREST + NEAREST = C.GL_NEAREST + NEVER = C.GL_NEVER + NICEST = C.GL_NICEST + NO_ERROR = C.GL_NO_ERROR + NONE = C.GL_NONE + NOOP = C.GL_NOOP + NORMAL_ARRAY_BUFFER_BINDING = C.GL_NORMAL_ARRAY_BUFFER_BINDING + NORMAL_ARRAY_POINTER = C.GL_NORMAL_ARRAY_POINTER + NORMAL_ARRAY_STRIDE = C.GL_NORMAL_ARRAY_STRIDE + NORMAL_ARRAY_TYPE = C.GL_NORMAL_ARRAY_TYPE + NORMAL_ARRAY = C.GL_NORMAL_ARRAY + NORMALIZE = C.GL_NORMALIZE + NORMAL_MAP = C.GL_NORMAL_MAP + NOR = C.GL_NOR + NOTEQUAL = C.GL_NOTEQUAL + NUM_COMPRESSED_TEXTURE_FORMATS = C.GL_NUM_COMPRESSED_TEXTURE_FORMATS + OBJECT_LINEAR = C.GL_OBJECT_LINEAR + OBJECT_PLANE = C.GL_OBJECT_PLANE + OBJECT_TYPE = C.GL_OBJECT_TYPE + ONE_MINUS_CONSTANT_ALPHA = C.GL_ONE_MINUS_CONSTANT_ALPHA + ONE_MINUS_CONSTANT_COLOR = C.GL_ONE_MINUS_CONSTANT_COLOR + ONE_MINUS_DST_ALPHA = C.GL_ONE_MINUS_DST_ALPHA + ONE_MINUS_DST_COLOR = C.GL_ONE_MINUS_DST_COLOR + ONE_MINUS_SRC_ALPHA = C.GL_ONE_MINUS_SRC_ALPHA + ONE_MINUS_SRC_COLOR = C.GL_ONE_MINUS_SRC_COLOR + ONE = C.GL_ONE + OPERAND0_ALPHA = C.GL_OPERAND0_ALPHA + OPERAND0_RGB = C.GL_OPERAND0_RGB + OPERAND1_ALPHA = C.GL_OPERAND1_ALPHA + OPERAND1_RGB = C.GL_OPERAND1_RGB + OPERAND2_ALPHA = C.GL_OPERAND2_ALPHA + OPERAND2_RGB = C.GL_OPERAND2_RGB + ORDER = C.GL_ORDER + OR_INVERTED = C.GL_OR_INVERTED + OR_REVERSE = C.GL_OR_REVERSE + OR = C.GL_OR + OUT_OF_MEMORY = C.GL_OUT_OF_MEMORY + PACK_ALIGNMENT = C.GL_PACK_ALIGNMENT + PACK_IMAGE_HEIGHT = C.GL_PACK_IMAGE_HEIGHT + PACK_LSB_FIRST = C.GL_PACK_LSB_FIRST + PACK_ROW_LENGTH = C.GL_PACK_ROW_LENGTH + PACK_SKIP_IMAGES = C.GL_PACK_SKIP_IMAGES + PACK_SKIP_PIXELS = C.GL_PACK_SKIP_PIXELS + PACK_SKIP_ROWS = C.GL_PACK_SKIP_ROWS + PACK_SWAP_BYTES = C.GL_PACK_SWAP_BYTES + PASS_THROUGH_TOKEN = C.GL_PASS_THROUGH_TOKEN + PERSPECTIVE_CORRECTION_HINT = C.GL_PERSPECTIVE_CORRECTION_HINT + PIXEL_MAP_A_TO_A_SIZE = C.GL_PIXEL_MAP_A_TO_A_SIZE + PIXEL_MAP_A_TO_A = C.GL_PIXEL_MAP_A_TO_A + PIXEL_MAP_B_TO_B_SIZE = C.GL_PIXEL_MAP_B_TO_B_SIZE + PIXEL_MAP_B_TO_B = C.GL_PIXEL_MAP_B_TO_B + PIXEL_MAP_G_TO_G_SIZE = C.GL_PIXEL_MAP_G_TO_G_SIZE + PIXEL_MAP_G_TO_G = C.GL_PIXEL_MAP_G_TO_G + PIXEL_MAP_I_TO_A_SIZE = C.GL_PIXEL_MAP_I_TO_A_SIZE + PIXEL_MAP_I_TO_A = C.GL_PIXEL_MAP_I_TO_A + PIXEL_MAP_I_TO_B_SIZE = C.GL_PIXEL_MAP_I_TO_B_SIZE + PIXEL_MAP_I_TO_B = C.GL_PIXEL_MAP_I_TO_B + PIXEL_MAP_I_TO_G_SIZE = C.GL_PIXEL_MAP_I_TO_G_SIZE + PIXEL_MAP_I_TO_G = C.GL_PIXEL_MAP_I_TO_G + PIXEL_MAP_I_TO_I_SIZE = C.GL_PIXEL_MAP_I_TO_I_SIZE + PIXEL_MAP_I_TO_I = C.GL_PIXEL_MAP_I_TO_I + PIXEL_MAP_I_TO_R_SIZE = C.GL_PIXEL_MAP_I_TO_R_SIZE + PIXEL_MAP_I_TO_R = C.GL_PIXEL_MAP_I_TO_R + PIXEL_MAP_R_TO_R_SIZE = C.GL_PIXEL_MAP_R_TO_R_SIZE + PIXEL_MAP_R_TO_R = C.GL_PIXEL_MAP_R_TO_R + PIXEL_MAP_S_TO_S_SIZE = C.GL_PIXEL_MAP_S_TO_S_SIZE + PIXEL_MAP_S_TO_S = C.GL_PIXEL_MAP_S_TO_S + PIXEL_MODE_BIT = C.GL_PIXEL_MODE_BIT + PIXEL_PACK_BUFFER_BINDING = C.GL_PIXEL_PACK_BUFFER_BINDING + PIXEL_PACK_BUFFER = C.GL_PIXEL_PACK_BUFFER + PIXEL_UNPACK_BUFFER_BINDING = C.GL_PIXEL_UNPACK_BUFFER_BINDING + PIXEL_UNPACK_BUFFER = C.GL_PIXEL_UNPACK_BUFFER + POINT_BIT = C.GL_POINT_BIT + POINT_DISTANCE_ATTENUATION = C.GL_POINT_DISTANCE_ATTENUATION + POINT_FADE_THRESHOLD_SIZE = C.GL_POINT_FADE_THRESHOLD_SIZE + POINT_SIZE_GRANULARITY = C.GL_POINT_SIZE_GRANULARITY + POINT_SIZE_MAX = C.GL_POINT_SIZE_MAX + POINT_SIZE_MIN = C.GL_POINT_SIZE_MIN + POINT_SIZE_RANGE = C.GL_POINT_SIZE_RANGE + POINT_SIZE = C.GL_POINT_SIZE + POINT_SMOOTH_HINT = C.GL_POINT_SMOOTH_HINT + POINT_SMOOTH = C.GL_POINT_SMOOTH + POINT_SPRITE_COORD_ORIGIN = C.GL_POINT_SPRITE_COORD_ORIGIN + POINT_SPRITE = C.GL_POINT_SPRITE + POINTS = C.GL_POINTS + POINT_TOKEN = C.GL_POINT_TOKEN + POINT = C.GL_POINT + POLYGON_BIT = C.GL_POLYGON_BIT + POLYGON_MODE = C.GL_POLYGON_MODE + POLYGON_OFFSET_FACTOR = C.GL_POLYGON_OFFSET_FACTOR + POLYGON_OFFSET_FILL = C.GL_POLYGON_OFFSET_FILL + POLYGON_OFFSET_LINE = C.GL_POLYGON_OFFSET_LINE + POLYGON_OFFSET_POINT = C.GL_POLYGON_OFFSET_POINT + POLYGON_OFFSET_UNITS = C.GL_POLYGON_OFFSET_UNITS + POLYGON_SMOOTH_HINT = C.GL_POLYGON_SMOOTH_HINT + POLYGON_SMOOTH = C.GL_POLYGON_SMOOTH + POLYGON_STIPPLE_BIT = C.GL_POLYGON_STIPPLE_BIT + POLYGON_STIPPLE = C.GL_POLYGON_STIPPLE + POLYGON_TOKEN = C.GL_POLYGON_TOKEN + POLYGON = C.GL_POLYGON + POSITION = C.GL_POSITION + POST_COLOR_MATRIX_ALPHA_BIAS = C.GL_POST_COLOR_MATRIX_ALPHA_BIAS + POST_COLOR_MATRIX_ALPHA_SCALE = C.GL_POST_COLOR_MATRIX_ALPHA_SCALE + POST_COLOR_MATRIX_BLUE_BIAS = C.GL_POST_COLOR_MATRIX_BLUE_BIAS + POST_COLOR_MATRIX_BLUE_SCALE = C.GL_POST_COLOR_MATRIX_BLUE_SCALE + POST_COLOR_MATRIX_COLOR_TABLE = C.GL_POST_COLOR_MATRIX_COLOR_TABLE + POST_COLOR_MATRIX_GREEN_BIAS = C.GL_POST_COLOR_MATRIX_GREEN_BIAS + POST_COLOR_MATRIX_GREEN_SCALE = C.GL_POST_COLOR_MATRIX_GREEN_SCALE + POST_COLOR_MATRIX_RED_BIAS = C.GL_POST_COLOR_MATRIX_RED_BIAS + POST_COLOR_MATRIX_RED_SCALE = C.GL_POST_COLOR_MATRIX_RED_SCALE + POST_CONVOLUTION_ALPHA_BIAS = C.GL_POST_CONVOLUTION_ALPHA_BIAS + POST_CONVOLUTION_ALPHA_SCALE = C.GL_POST_CONVOLUTION_ALPHA_SCALE + POST_CONVOLUTION_BLUE_BIAS = C.GL_POST_CONVOLUTION_BLUE_BIAS + POST_CONVOLUTION_BLUE_SCALE = C.GL_POST_CONVOLUTION_BLUE_SCALE + POST_CONVOLUTION_COLOR_TABLE = C.GL_POST_CONVOLUTION_COLOR_TABLE + POST_CONVOLUTION_GREEN_BIAS = C.GL_POST_CONVOLUTION_GREEN_BIAS + POST_CONVOLUTION_GREEN_SCALE = C.GL_POST_CONVOLUTION_GREEN_SCALE + POST_CONVOLUTION_RED_BIAS = C.GL_POST_CONVOLUTION_RED_BIAS + POST_CONVOLUTION_RED_SCALE = C.GL_POST_CONVOLUTION_RED_SCALE + PREVIOUS = C.GL_PREVIOUS + PRIMARY_COLOR = C.GL_PRIMARY_COLOR + PRIMITIVE_RESTART_INDEX = C.GL_PRIMITIVE_RESTART_INDEX + PRIMITIVE_RESTART = C.GL_PRIMITIVE_RESTART + PRIMITIVES_GENERATED = C.GL_PRIMITIVES_GENERATED + PROGRAM_POINT_SIZE = C.GL_PROGRAM_POINT_SIZE + PROJECTION_MATRIX = C.GL_PROJECTION_MATRIX + PROJECTION_STACK_DEPTH = C.GL_PROJECTION_STACK_DEPTH + PROJECTION = C.GL_PROJECTION + PROVOKING_VERTEX = C.GL_PROVOKING_VERTEX + PROXY_COLOR_TABLE = C.GL_PROXY_COLOR_TABLE + PROXY_HISTOGRAM = C.GL_PROXY_HISTOGRAM + PROXY_POST_COLOR_MATRIX_COLOR_TABLE = C.GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE + PROXY_POST_CONVOLUTION_COLOR_TABLE = C.GL_PROXY_POST_CONVOLUTION_COLOR_TABLE + PROXY_TEXTURE_1D_ARRAY = C.GL_PROXY_TEXTURE_1D_ARRAY + PROXY_TEXTURE_1D = C.GL_PROXY_TEXTURE_1D + PROXY_TEXTURE_2D_ARRAY = C.GL_PROXY_TEXTURE_2D_ARRAY + PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY = C.GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY + PROXY_TEXTURE_2D_MULTISAMPLE = C.GL_PROXY_TEXTURE_2D_MULTISAMPLE + PROXY_TEXTURE_2D = C.GL_PROXY_TEXTURE_2D + PROXY_TEXTURE_3D = C.GL_PROXY_TEXTURE_3D + PROXY_TEXTURE_CUBE_MAP_ARRAY = C.GL_PROXY_TEXTURE_CUBE_MAP_ARRAY + PROXY_TEXTURE_CUBE_MAP = C.GL_PROXY_TEXTURE_CUBE_MAP + PROXY_TEXTURE_RECTANGLE = C.GL_PROXY_TEXTURE_RECTANGLE + QUADRATIC_ATTENUATION = C.GL_QUADRATIC_ATTENUATION + QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = C.GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION + QUAD_STRIP = C.GL_QUAD_STRIP + QUADS = C.GL_QUADS + QUERY_BY_REGION_NO_WAIT = C.GL_QUERY_BY_REGION_NO_WAIT + QUERY_BY_REGION_WAIT = C.GL_QUERY_BY_REGION_WAIT + QUERY_COUNTER_BITS = C.GL_QUERY_COUNTER_BITS + QUERY_NO_WAIT = C.GL_QUERY_NO_WAIT + QUERY_RESULT_AVAILABLE = C.GL_QUERY_RESULT_AVAILABLE + QUERY_RESULT = C.GL_QUERY_RESULT + QUERY_WAIT = C.GL_QUERY_WAIT + Q = C.GL_Q + R11F_G11F_B10F = C.GL_R11F_G11F_B10F + R16F = C.GL_R16F + R16I = C.GL_R16I + R16_SNORM = C.GL_R16_SNORM + R16UI = C.GL_R16UI + R16 = C.GL_R16 + R32F = C.GL_R32F + R32I = C.GL_R32I + R32UI = C.GL_R32UI + R3_G3_B2 = C.GL_R3_G3_B2 + R8I = C.GL_R8I + R8_SNORM = C.GL_R8_SNORM + R8UI = C.GL_R8UI + R8 = C.GL_R8 + RASTERIZER_DISCARD = C.GL_RASTERIZER_DISCARD + READ_BUFFER = C.GL_READ_BUFFER + READ_FRAMEBUFFER_BINDING = C.GL_READ_FRAMEBUFFER_BINDING + READ_FRAMEBUFFER = C.GL_READ_FRAMEBUFFER + READ_ONLY = C.GL_READ_ONLY + READ_WRITE = C.GL_READ_WRITE + RED_BIAS = C.GL_RED_BIAS + RED_BITS = C.GL_RED_BITS + RED_INTEGER = C.GL_RED_INTEGER + RED_SCALE = C.GL_RED_SCALE + RED_SNORM = C.GL_RED_SNORM + REDUCE = C.GL_REDUCE + RED = C.GL_RED + REFLECTION_MAP = C.GL_REFLECTION_MAP + RENDERBUFFER_ALPHA_SIZE = C.GL_RENDERBUFFER_ALPHA_SIZE + RENDERBUFFER_BINDING = C.GL_RENDERBUFFER_BINDING + RENDERBUFFER_BLUE_SIZE = C.GL_RENDERBUFFER_BLUE_SIZE + RENDERBUFFER_DEPTH_SIZE = C.GL_RENDERBUFFER_DEPTH_SIZE + RENDERBUFFER_GREEN_SIZE = C.GL_RENDERBUFFER_GREEN_SIZE + RENDERBUFFER_HEIGHT = C.GL_RENDERBUFFER_HEIGHT + RENDERBUFFER_INTERNAL_FORMAT = C.GL_RENDERBUFFER_INTERNAL_FORMAT + RENDERBUFFER_RED_SIZE = C.GL_RENDERBUFFER_RED_SIZE + RENDERBUFFER_SAMPLES = C.GL_RENDERBUFFER_SAMPLES + RENDERBUFFER_STENCIL_SIZE = C.GL_RENDERBUFFER_STENCIL_SIZE + RENDERBUFFER_WIDTH = C.GL_RENDERBUFFER_WIDTH + RENDERBUFFER = C.GL_RENDERBUFFER + RENDERER = C.GL_RENDERER + RENDER_MODE = C.GL_RENDER_MODE + RENDER = C.GL_RENDER + REND_screen_coordinates = C.GL_REND_screen_coordinates + REPEAT = C.GL_REPEAT + REPLACE = C.GL_REPLACE + REPLICATE_BORDER = C.GL_REPLICATE_BORDER + RESCALE_NORMAL = C.GL_RESCALE_NORMAL + RETURN = C.GL_RETURN + RG16F = C.GL_RG16F + RG16I = C.GL_RG16I + RG16_SNORM = C.GL_RG16_SNORM + RG16UI = C.GL_RG16UI + RG16 = C.GL_RG16 + RG32F = C.GL_RG32F + RG32I = C.GL_RG32I + RG32UI = C.GL_RG32UI + RG8I = C.GL_RG8I + RG8_SNORM = C.GL_RG8_SNORM + RG8UI = C.GL_RG8UI + RG8 = C.GL_RG8 + RGB10_A2 = C.GL_RGB10_A2 + RGB10 = C.GL_RGB10 + RGB12 = C.GL_RGB12 + RGB16F = C.GL_RGB16F + RGB16I = C.GL_RGB16I + RGB16_SNORM = C.GL_RGB16_SNORM + RGB16UI = C.GL_RGB16UI + RGB16 = C.GL_RGB16 + RGB32F = C.GL_RGB32F + RGB32I = C.GL_RGB32I + RGB32UI = C.GL_RGB32UI + RGB4 = C.GL_RGB4 + RGB5_A1 = C.GL_RGB5_A1 + RGB5 = C.GL_RGB5 + RGB8I = C.GL_RGB8I + RGB8_SNORM = C.GL_RGB8_SNORM + RGB8UI = C.GL_RGB8UI + RGB8 = C.GL_RGB8 + RGB9_E5 = C.GL_RGB9_E5 + RGBA12 = C.GL_RGBA12 + RGBA16F = C.GL_RGBA16F + RGBA16I = C.GL_RGBA16I + RGBA16_SNORM = C.GL_RGBA16_SNORM + RGBA16UI = C.GL_RGBA16UI + RGBA16 = C.GL_RGBA16 + RGBA2 = C.GL_RGBA2 + RGBA32F = C.GL_RGBA32F + RGBA32I = C.GL_RGBA32I + RGBA32UI = C.GL_RGBA32UI + RGBA4 = C.GL_RGBA4 + RGBA8I = C.GL_RGBA8I + RGBA8_SNORM = C.GL_RGBA8_SNORM + RGBA8UI = C.GL_RGBA8UI + RGBA8 = C.GL_RGBA8 + RGBA_INTEGER = C.GL_RGBA_INTEGER + RGBA_MODE = C.GL_RGBA_MODE + RGBA_SNORM = C.GL_RGBA_SNORM + RGBA = C.GL_RGBA + RGB_INTEGER = C.GL_RGB_INTEGER + RGB_SCALE = C.GL_RGB_SCALE + RGB_SNORM = C.GL_RGB_SNORM + RGB = C.GL_RGB + RG_INTEGER = C.GL_RG_INTEGER + RG_SNORM = C.GL_RG_SNORM + RG = C.GL_RG + RIGHT = C.GL_RIGHT + R = C.GL_R + SAMPLE_ALPHA_TO_COVERAGE = C.GL_SAMPLE_ALPHA_TO_COVERAGE + SAMPLE_ALPHA_TO_ONE = C.GL_SAMPLE_ALPHA_TO_ONE + SAMPLE_BUFFERS = C.GL_SAMPLE_BUFFERS + SAMPLE_COVERAGE_INVERT = C.GL_SAMPLE_COVERAGE_INVERT + SAMPLE_COVERAGE_VALUE = C.GL_SAMPLE_COVERAGE_VALUE + SAMPLE_COVERAGE = C.GL_SAMPLE_COVERAGE + SAMPLE_MASK_VALUE = C.GL_SAMPLE_MASK_VALUE + SAMPLE_MASK = C.GL_SAMPLE_MASK + SAMPLE_POSITION = C.GL_SAMPLE_POSITION + SAMPLER_1D_ARRAY_SHADOW = C.GL_SAMPLER_1D_ARRAY_SHADOW + SAMPLER_1D_ARRAY = C.GL_SAMPLER_1D_ARRAY + SAMPLER_1D_SHADOW = C.GL_SAMPLER_1D_SHADOW + SAMPLER_1D = C.GL_SAMPLER_1D + SAMPLER_2D_ARRAY_SHADOW = C.GL_SAMPLER_2D_ARRAY_SHADOW + SAMPLER_2D_ARRAY = C.GL_SAMPLER_2D_ARRAY + SAMPLER_2D_MULTISAMPLE_ARRAY = C.GL_SAMPLER_2D_MULTISAMPLE_ARRAY + SAMPLER_2D_MULTISAMPLE = C.GL_SAMPLER_2D_MULTISAMPLE + SAMPLER_2D_RECT_SHADOW = C.GL_SAMPLER_2D_RECT_SHADOW + SAMPLER_2D_RECT = C.GL_SAMPLER_2D_RECT + SAMPLER_2D_SHADOW = C.GL_SAMPLER_2D_SHADOW + SAMPLER_2D = C.GL_SAMPLER_2D + SAMPLER_3D = C.GL_SAMPLER_3D + SAMPLER_BUFFER = C.GL_SAMPLER_BUFFER + SAMPLER_CUBE_MAP_ARRAY_SHADOW = C.GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW + SAMPLER_CUBE_MAP_ARRAY = C.GL_SAMPLER_CUBE_MAP_ARRAY + SAMPLER_CUBE_SHADOW = C.GL_SAMPLER_CUBE_SHADOW + SAMPLER_CUBE = C.GL_SAMPLER_CUBE + SAMPLE_SHADING = C.GL_SAMPLE_SHADING + SAMPLES_PASSED = C.GL_SAMPLES_PASSED + SAMPLES = C.GL_SAMPLES + SCISSOR_BIT = C.GL_SCISSOR_BIT + SCISSOR_BOX = C.GL_SCISSOR_BOX + SCISSOR_TEST = C.GL_SCISSOR_TEST + SCREEN_COORDINATES_REND = C.GL_SCREEN_COORDINATES_REND + SECONDARY_COLOR_ARRAY_BUFFER_BINDING = C.GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING + SECONDARY_COLOR_ARRAY_POINTER = C.GL_SECONDARY_COLOR_ARRAY_POINTER + SECONDARY_COLOR_ARRAY_SIZE = C.GL_SECONDARY_COLOR_ARRAY_SIZE + SECONDARY_COLOR_ARRAY_STRIDE = C.GL_SECONDARY_COLOR_ARRAY_STRIDE + SECONDARY_COLOR_ARRAY_TYPE = C.GL_SECONDARY_COLOR_ARRAY_TYPE + SECONDARY_COLOR_ARRAY = C.GL_SECONDARY_COLOR_ARRAY + SELECTION_BUFFER_POINTER = C.GL_SELECTION_BUFFER_POINTER + SELECTION_BUFFER_SIZE = C.GL_SELECTION_BUFFER_SIZE + SELECT = C.GL_SELECT + SEPARABLE_2D = C.GL_SEPARABLE_2D + SEPARATE_ATTRIBS = C.GL_SEPARATE_ATTRIBS + SEPARATE_SPECULAR_COLOR = C.GL_SEPARATE_SPECULAR_COLOR + SET = C.GL_SET + SHADE_MODEL = C.GL_SHADE_MODEL + SHADER_SOURCE_LENGTH = C.GL_SHADER_SOURCE_LENGTH + SHADER_TYPE = C.GL_SHADER_TYPE + SHADING_LANGUAGE_VERSION = C.GL_SHADING_LANGUAGE_VERSION + SHININESS = C.GL_SHININESS + SHORT = C.GL_SHORT + SIGNALED = C.GL_SIGNALED + SIGNED_NORMALIZED = C.GL_SIGNED_NORMALIZED + SINGLE_COLOR = C.GL_SINGLE_COLOR + SLUMINANCE8_ALPHA8 = C.GL_SLUMINANCE8_ALPHA8 + SLUMINANCE8 = C.GL_SLUMINANCE8 + SLUMINANCE_ALPHA = C.GL_SLUMINANCE_ALPHA + SLUMINANCE = C.GL_SLUMINANCE + SMOOTH_LINE_WIDTH_GRANULARITY = C.GL_SMOOTH_LINE_WIDTH_GRANULARITY + SMOOTH_LINE_WIDTH_RANGE = C.GL_SMOOTH_LINE_WIDTH_RANGE + SMOOTH_POINT_SIZE_GRANULARITY = C.GL_SMOOTH_POINT_SIZE_GRANULARITY + SMOOTH_POINT_SIZE_RANGE = C.GL_SMOOTH_POINT_SIZE_RANGE + SMOOTH = C.GL_SMOOTH + SOURCE0_ALPHA = C.GL_SOURCE0_ALPHA + SOURCE0_RGB = C.GL_SOURCE0_RGB + SOURCE1_ALPHA = C.GL_SOURCE1_ALPHA + SOURCE1_RGB = C.GL_SOURCE1_RGB + SOURCE2_ALPHA = C.GL_SOURCE2_ALPHA + SOURCE2_RGB = C.GL_SOURCE2_RGB + SPECULAR = C.GL_SPECULAR + SPHERE_MAP = C.GL_SPHERE_MAP + SPOT_CUTOFF = C.GL_SPOT_CUTOFF + SPOT_DIRECTION = C.GL_SPOT_DIRECTION + SPOT_EXPONENT = C.GL_SPOT_EXPONENT + SRC0_ALPHA = C.GL_SRC0_ALPHA + SRC0_RGB = C.GL_SRC0_RGB + SRC1_ALPHA = C.GL_SRC1_ALPHA + SRC1_RGB = C.GL_SRC1_RGB + SRC2_ALPHA = C.GL_SRC2_ALPHA + SRC2_RGB = C.GL_SRC2_RGB + SRC_ALPHA_SATURATE = C.GL_SRC_ALPHA_SATURATE + SRC_ALPHA = C.GL_SRC_ALPHA + SRC_COLOR = C.GL_SRC_COLOR + SRGB8_ALPHA8 = C.GL_SRGB8_ALPHA8 + SRGB8 = C.GL_SRGB8 + SRGB_ALPHA = C.GL_SRGB_ALPHA + SRGB = C.GL_SRGB + STACK_OVERFLOW = C.GL_STACK_OVERFLOW + STACK_UNDERFLOW = C.GL_STACK_UNDERFLOW + STATIC_COPY = C.GL_STATIC_COPY + STATIC_DRAW = C.GL_STATIC_DRAW + STATIC_READ = C.GL_STATIC_READ + STENCIL_ATTACHMENT = C.GL_STENCIL_ATTACHMENT + STENCIL_BACK_FAIL = C.GL_STENCIL_BACK_FAIL + STENCIL_BACK_FUNC = C.GL_STENCIL_BACK_FUNC + STENCIL_BACK_PASS_DEPTH_FAIL = C.GL_STENCIL_BACK_PASS_DEPTH_FAIL + STENCIL_BACK_PASS_DEPTH_PASS = C.GL_STENCIL_BACK_PASS_DEPTH_PASS + STENCIL_BACK_REF = C.GL_STENCIL_BACK_REF + STENCIL_BACK_VALUE_MASK = C.GL_STENCIL_BACK_VALUE_MASK + STENCIL_BACK_WRITEMASK = C.GL_STENCIL_BACK_WRITEMASK + STENCIL_BITS = C.GL_STENCIL_BITS + STENCIL_BUFFER_BIT = C.GL_STENCIL_BUFFER_BIT + STENCIL_BUFFER = C.GL_STENCIL_BUFFER + STENCIL_CLEAR_VALUE = C.GL_STENCIL_CLEAR_VALUE + STENCIL_FAIL = C.GL_STENCIL_FAIL + STENCIL_FUNC = C.GL_STENCIL_FUNC + STENCIL_INDEX16 = C.GL_STENCIL_INDEX16 + STENCIL_INDEX1 = C.GL_STENCIL_INDEX1 + STENCIL_INDEX4 = C.GL_STENCIL_INDEX4 + STENCIL_INDEX8 = C.GL_STENCIL_INDEX8 + STENCIL_INDEX = C.GL_STENCIL_INDEX + STENCIL_PASS_DEPTH_FAIL = C.GL_STENCIL_PASS_DEPTH_FAIL + STENCIL_PASS_DEPTH_PASS = C.GL_STENCIL_PASS_DEPTH_PASS + STENCIL_REF = C.GL_STENCIL_REF + STENCIL_TEST = C.GL_STENCIL_TEST + STENCIL_VALUE_MASK = C.GL_STENCIL_VALUE_MASK + STENCIL_WRITEMASK = C.GL_STENCIL_WRITEMASK + STENCIL = C.GL_STENCIL + STEREO = C.GL_STEREO + STREAM_COPY = C.GL_STREAM_COPY + STREAM_DRAW = C.GL_STREAM_DRAW + STREAM_READ = C.GL_STREAM_READ + SUBPIXEL_BITS = C.GL_SUBPIXEL_BITS + SUBTRACT = C.GL_SUBTRACT + SYNC_CONDITION = C.GL_SYNC_CONDITION + SYNC_FENCE = C.GL_SYNC_FENCE + SYNC_FLAGS = C.GL_SYNC_FLAGS + SYNC_FLUSH_COMMANDS_BIT = C.GL_SYNC_FLUSH_COMMANDS_BIT + SYNC_GPU_COMMANDS_COMPLETE = C.GL_SYNC_GPU_COMMANDS_COMPLETE + SYNC_STATUS = C.GL_SYNC_STATUS + S = C.GL_S + T2F_C3F_V3F = C.GL_T2F_C3F_V3F + T2F_C4F_N3F_V3F = C.GL_T2F_C4F_N3F_V3F + T2F_C4UB_V3F = C.GL_T2F_C4UB_V3F + T2F_N3F_V3F = C.GL_T2F_N3F_V3F + T2F_V3F = C.GL_T2F_V3F + T4F_C4F_N3F_V4F = C.GL_T4F_C4F_N3F_V4F + T4F_V4F = C.GL_T4F_V4F + TABLE_TOO_LARGE = C.GL_TABLE_TOO_LARGE + TEXTURE0 = C.GL_TEXTURE0 + TEXTURE10 = C.GL_TEXTURE10 + TEXTURE11 = C.GL_TEXTURE11 + TEXTURE12 = C.GL_TEXTURE12 + TEXTURE13 = C.GL_TEXTURE13 + TEXTURE14 = C.GL_TEXTURE14 + TEXTURE15 = C.GL_TEXTURE15 + TEXTURE16 = C.GL_TEXTURE16 + TEXTURE17 = C.GL_TEXTURE17 + TEXTURE18 = C.GL_TEXTURE18 + TEXTURE19 = C.GL_TEXTURE19 + TEXTURE_1D_ARRAY = C.GL_TEXTURE_1D_ARRAY + TEXTURE_1D = C.GL_TEXTURE_1D + TEXTURE1 = C.GL_TEXTURE1 + TEXTURE20 = C.GL_TEXTURE20 + TEXTURE21 = C.GL_TEXTURE21 + TEXTURE22 = C.GL_TEXTURE22 + TEXTURE23 = C.GL_TEXTURE23 + TEXTURE24 = C.GL_TEXTURE24 + TEXTURE25 = C.GL_TEXTURE25 + TEXTURE26 = C.GL_TEXTURE26 + TEXTURE27 = C.GL_TEXTURE27 + TEXTURE28 = C.GL_TEXTURE28 + TEXTURE29 = C.GL_TEXTURE29 + TEXTURE_2D_ARRAY = C.GL_TEXTURE_2D_ARRAY + TEXTURE_2D_MULTISAMPLE_ARRAY = C.GL_TEXTURE_2D_MULTISAMPLE_ARRAY + TEXTURE_2D_MULTISAMPLE = C.GL_TEXTURE_2D_MULTISAMPLE + TEXTURE_2D = C.GL_TEXTURE_2D + TEXTURE2 = C.GL_TEXTURE2 + TEXTURE30 = C.GL_TEXTURE30 + TEXTURE31 = C.GL_TEXTURE31 + TEXTURE_3D = C.GL_TEXTURE_3D + TEXTURE3 = C.GL_TEXTURE3 + TEXTURE4 = C.GL_TEXTURE4 + TEXTURE5 = C.GL_TEXTURE5 + TEXTURE6 = C.GL_TEXTURE6 + TEXTURE7 = C.GL_TEXTURE7 + TEXTURE8 = C.GL_TEXTURE8 + TEXTURE9 = C.GL_TEXTURE9 + TEXTURE_ALPHA_SIZE = C.GL_TEXTURE_ALPHA_SIZE + TEXTURE_ALPHA_TYPE = C.GL_TEXTURE_ALPHA_TYPE + TEXTURE_BASE_LEVEL = C.GL_TEXTURE_BASE_LEVEL + TEXTURE_BINDING_1D_ARRAY = C.GL_TEXTURE_BINDING_1D_ARRAY + TEXTURE_BINDING_1D = C.GL_TEXTURE_BINDING_1D + TEXTURE_BINDING_2D_ARRAY = C.GL_TEXTURE_BINDING_2D_ARRAY + TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY = C.GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY + TEXTURE_BINDING_2D_MULTISAMPLE = C.GL_TEXTURE_BINDING_2D_MULTISAMPLE + TEXTURE_BINDING_2D = C.GL_TEXTURE_BINDING_2D + TEXTURE_BINDING_3D = C.GL_TEXTURE_BINDING_3D + TEXTURE_BINDING_BUFFER = C.GL_TEXTURE_BINDING_BUFFER + TEXTURE_BINDING_CUBE_MAP_ARRAY = C.GL_TEXTURE_BINDING_CUBE_MAP_ARRAY + TEXTURE_BINDING_CUBE_MAP = C.GL_TEXTURE_BINDING_CUBE_MAP + TEXTURE_BINDING_RECTANGLE = C.GL_TEXTURE_BINDING_RECTANGLE + TEXTURE_BIT = C.GL_TEXTURE_BIT + TEXTURE_BLUE_SIZE = C.GL_TEXTURE_BLUE_SIZE + TEXTURE_BLUE_TYPE = C.GL_TEXTURE_BLUE_TYPE + TEXTURE_BORDER_COLOR = C.GL_TEXTURE_BORDER_COLOR + TEXTURE_BORDER = C.GL_TEXTURE_BORDER + TEXTURE_BUFFER_DATA_STORE_BINDING = C.GL_TEXTURE_BUFFER_DATA_STORE_BINDING + TEXTURE_BUFFER_FORMAT = C.GL_TEXTURE_BUFFER_FORMAT + TEXTURE_BUFFER = C.GL_TEXTURE_BUFFER + TEXTURE_COMPARE_FUNC = C.GL_TEXTURE_COMPARE_FUNC + TEXTURE_COMPARE_MODE = C.GL_TEXTURE_COMPARE_MODE + TEXTURE_COMPONENTS = C.GL_TEXTURE_COMPONENTS + TEXTURE_COMPRESSED_IMAGE_SIZE = C.GL_TEXTURE_COMPRESSED_IMAGE_SIZE + TEXTURE_COMPRESSED = C.GL_TEXTURE_COMPRESSED + TEXTURE_COMPRESSION_HINT = C.GL_TEXTURE_COMPRESSION_HINT + TEXTURE_COORD_ARRAY_BUFFER_BINDING = C.GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING + TEXTURE_COORD_ARRAY_POINTER = C.GL_TEXTURE_COORD_ARRAY_POINTER + TEXTURE_COORD_ARRAY_SIZE = C.GL_TEXTURE_COORD_ARRAY_SIZE + TEXTURE_COORD_ARRAY_STRIDE = C.GL_TEXTURE_COORD_ARRAY_STRIDE + TEXTURE_COORD_ARRAY_TYPE = C.GL_TEXTURE_COORD_ARRAY_TYPE + TEXTURE_COORD_ARRAY = C.GL_TEXTURE_COORD_ARRAY + TEXTURE_CUBE_MAP_ARRAY = C.GL_TEXTURE_CUBE_MAP_ARRAY + TEXTURE_CUBE_MAP_NEGATIVE_X = C.GL_TEXTURE_CUBE_MAP_NEGATIVE_X + TEXTURE_CUBE_MAP_NEGATIVE_Y = C.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y + TEXTURE_CUBE_MAP_NEGATIVE_Z = C.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + TEXTURE_CUBE_MAP_POSITIVE_X = C.GL_TEXTURE_CUBE_MAP_POSITIVE_X + TEXTURE_CUBE_MAP_POSITIVE_Y = C.GL_TEXTURE_CUBE_MAP_POSITIVE_Y + TEXTURE_CUBE_MAP_POSITIVE_Z = C.GL_TEXTURE_CUBE_MAP_POSITIVE_Z + TEXTURE_CUBE_MAP_SEAMLESS = C.GL_TEXTURE_CUBE_MAP_SEAMLESS + TEXTURE_CUBE_MAP = C.GL_TEXTURE_CUBE_MAP + TEXTURE_DEPTH_SIZE = C.GL_TEXTURE_DEPTH_SIZE + TEXTURE_DEPTH_TYPE = C.GL_TEXTURE_DEPTH_TYPE + TEXTURE_DEPTH = C.GL_TEXTURE_DEPTH + TEXTURE_ENV_COLOR = C.GL_TEXTURE_ENV_COLOR + TEXTURE_ENV_MODE = C.GL_TEXTURE_ENV_MODE + TEXTURE_ENV = C.GL_TEXTURE_ENV + TEXTURE_FILTER_CONTROL = C.GL_TEXTURE_FILTER_CONTROL + TEXTURE_FIXED_SAMPLE_LOCATIONS = C.GL_TEXTURE_FIXED_SAMPLE_LOCATIONS + TEXTURE_GEN_MODE = C.GL_TEXTURE_GEN_MODE + TEXTURE_GEN_Q = C.GL_TEXTURE_GEN_Q + TEXTURE_GEN_R = C.GL_TEXTURE_GEN_R + TEXTURE_GEN_S = C.GL_TEXTURE_GEN_S + TEXTURE_GEN_T = C.GL_TEXTURE_GEN_T + TEXTURE_GREEN_SIZE = C.GL_TEXTURE_GREEN_SIZE + TEXTURE_GREEN_TYPE = C.GL_TEXTURE_GREEN_TYPE + TEXTURE_HEIGHT = C.GL_TEXTURE_HEIGHT + TEXTURE_INTENSITY_SIZE = C.GL_TEXTURE_INTENSITY_SIZE + TEXTURE_INTENSITY_TYPE = C.GL_TEXTURE_INTENSITY_TYPE + TEXTURE_INTERNAL_FORMAT = C.GL_TEXTURE_INTERNAL_FORMAT + TEXTURE_LOD_BIAS = C.GL_TEXTURE_LOD_BIAS + TEXTURE_LUMINANCE_SIZE = C.GL_TEXTURE_LUMINANCE_SIZE + TEXTURE_LUMINANCE_TYPE = C.GL_TEXTURE_LUMINANCE_TYPE + TEXTURE_MAG_FILTER = C.GL_TEXTURE_MAG_FILTER + TEXTURE_MATRIX = C.GL_TEXTURE_MATRIX + TEXTURE_MAX_LEVEL = C.GL_TEXTURE_MAX_LEVEL + TEXTURE_MAX_LOD = C.GL_TEXTURE_MAX_LOD + TEXTURE_MIN_FILTER = C.GL_TEXTURE_MIN_FILTER + TEXTURE_MIN_LOD = C.GL_TEXTURE_MIN_LOD + TEXTURE_PRIORITY = C.GL_TEXTURE_PRIORITY + TEXTURE_RECTANGLE = C.GL_TEXTURE_RECTANGLE + TEXTURE_RED_SIZE = C.GL_TEXTURE_RED_SIZE + TEXTURE_RED_TYPE = C.GL_TEXTURE_RED_TYPE + TEXTURE_RESIDENT = C.GL_TEXTURE_RESIDENT + TEXTURE_SAMPLES = C.GL_TEXTURE_SAMPLES + TEXTURE_SHARED_SIZE = C.GL_TEXTURE_SHARED_SIZE + TEXTURE_STACK_DEPTH = C.GL_TEXTURE_STACK_DEPTH + TEXTURE_STENCIL_SIZE = C.GL_TEXTURE_STENCIL_SIZE + TEXTURE_WIDTH = C.GL_TEXTURE_WIDTH + TEXTURE_WRAP_R = C.GL_TEXTURE_WRAP_R + TEXTURE_WRAP_S = C.GL_TEXTURE_WRAP_S + TEXTURE_WRAP_T = C.GL_TEXTURE_WRAP_T + TEXTURE = C.GL_TEXTURE + TIMEOUT_EXPIRED = C.GL_TIMEOUT_EXPIRED + TIMEOUT_IGNORED = C.GL_TIMEOUT_IGNORED + TIMESTAMP = C.GL_TIMESTAMP + TIME_ELAPSED = C.GL_TIME_ELAPSED + TRANSFORM_FEEDBACK = C.GL_TRANSFORM_FEEDBACK + TRANSFORM_BIT = C.GL_TRANSFORM_BIT + TRANSFORM_FEEDBACK_BUFFER_BINDING = C.GL_TRANSFORM_FEEDBACK_BUFFER_BINDING + TRANSFORM_FEEDBACK_BUFFER_MODE = C.GL_TRANSFORM_FEEDBACK_BUFFER_MODE + TRANSFORM_FEEDBACK_BUFFER_SIZE = C.GL_TRANSFORM_FEEDBACK_BUFFER_SIZE + TRANSFORM_FEEDBACK_BUFFER_START = C.GL_TRANSFORM_FEEDBACK_BUFFER_START + TRANSFORM_FEEDBACK_BUFFER = C.GL_TRANSFORM_FEEDBACK_BUFFER + TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = C.GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN + TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH = C.GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH + TRANSFORM_FEEDBACK_VARYINGS = C.GL_TRANSFORM_FEEDBACK_VARYINGS + TRANSPOSE_COLOR_MATRIX = C.GL_TRANSPOSE_COLOR_MATRIX + TRANSPOSE_MODELVIEW_MATRIX = C.GL_TRANSPOSE_MODELVIEW_MATRIX + TRANSPOSE_PROJECTION_MATRIX = C.GL_TRANSPOSE_PROJECTION_MATRIX + TRANSPOSE_TEXTURE_MATRIX = C.GL_TRANSPOSE_TEXTURE_MATRIX + TRIANGLE_FAN = C.GL_TRIANGLE_FAN + TRIANGLES_ADJACENCY = C.GL_TRIANGLES_ADJACENCY + TRIANGLE_STRIP_ADJACENCY = C.GL_TRIANGLE_STRIP_ADJACENCY + TRIANGLE_STRIP = C.GL_TRIANGLE_STRIP + TRIANGLES = C.GL_TRIANGLES + TRUE = C.GL_TRUE + T = C.GL_T + UNIFORM_ARRAY_STRIDE = C.GL_UNIFORM_ARRAY_STRIDE + UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = C.GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES + UNIFORM_BLOCK_ACTIVE_UNIFORMS = C.GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS + UNIFORM_BLOCK_BINDING = C.GL_UNIFORM_BLOCK_BINDING + UNIFORM_BLOCK_DATA_SIZE = C.GL_UNIFORM_BLOCK_DATA_SIZE + UNIFORM_BLOCK_INDEX = C.GL_UNIFORM_BLOCK_INDEX + UNIFORM_BLOCK_NAME_LENGTH = C.GL_UNIFORM_BLOCK_NAME_LENGTH + UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = C.GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER + UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = C.GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER + UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = C.GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER + UNIFORM_BUFFER_BINDING = C.GL_UNIFORM_BUFFER_BINDING + UNIFORM_BUFFER_OFFSET_ALIGNMENT = C.GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT + UNIFORM_BUFFER_SIZE = C.GL_UNIFORM_BUFFER_SIZE + UNIFORM_BUFFER_START = C.GL_UNIFORM_BUFFER_START + UNIFORM_BUFFER = C.GL_UNIFORM_BUFFER + UNIFORM_IS_ROW_MAJOR = C.GL_UNIFORM_IS_ROW_MAJOR + UNIFORM_MATRIX_STRIDE = C.GL_UNIFORM_MATRIX_STRIDE + UNIFORM_NAME_LENGTH = C.GL_UNIFORM_NAME_LENGTH + UNIFORM_OFFSET = C.GL_UNIFORM_OFFSET + UNIFORM_SIZE = C.GL_UNIFORM_SIZE + UNIFORM_TYPE = C.GL_UNIFORM_TYPE + UNPACK_ALIGNMENT = C.GL_UNPACK_ALIGNMENT + UNPACK_IMAGE_HEIGHT = C.GL_UNPACK_IMAGE_HEIGHT + UNPACK_LSB_FIRST = C.GL_UNPACK_LSB_FIRST + UNPACK_ROW_LENGTH = C.GL_UNPACK_ROW_LENGTH + UNPACK_SKIP_IMAGES = C.GL_UNPACK_SKIP_IMAGES + UNPACK_SKIP_PIXELS = C.GL_UNPACK_SKIP_PIXELS + UNPACK_SKIP_ROWS = C.GL_UNPACK_SKIP_ROWS + UNPACK_SWAP_BYTES = C.GL_UNPACK_SWAP_BYTES + UNSIGNALED = C.GL_UNSIGNALED + UNSIGNED_BYTE_2_3_3_REV = C.GL_UNSIGNED_BYTE_2_3_3_REV + UNSIGNED_BYTE_3_3_2 = C.GL_UNSIGNED_BYTE_3_3_2 + UNSIGNED_BYTE = C.GL_UNSIGNED_BYTE + UNSIGNED_INT_10_10_10_2 = C.GL_UNSIGNED_INT_10_10_10_2 + UNSIGNED_INT_10F_11F_11F_REV = C.GL_UNSIGNED_INT_10F_11F_11F_REV + UNSIGNED_INT_2_10_10_10_REV = C.GL_UNSIGNED_INT_2_10_10_10_REV + UNSIGNED_INT_24_8 = C.GL_UNSIGNED_INT_24_8 + UNSIGNED_INT_5_9_9_9_REV = C.GL_UNSIGNED_INT_5_9_9_9_REV + UNSIGNED_INT_8_8_8_8_REV = C.GL_UNSIGNED_INT_8_8_8_8_REV + UNSIGNED_INT_8_8_8_8 = C.GL_UNSIGNED_INT_8_8_8_8 + UNSIGNED_INT_SAMPLER_1D_ARRAY = C.GL_UNSIGNED_INT_SAMPLER_1D_ARRAY + UNSIGNED_INT_SAMPLER_1D = C.GL_UNSIGNED_INT_SAMPLER_1D + UNSIGNED_INT_SAMPLER_2D_ARRAY = C.GL_UNSIGNED_INT_SAMPLER_2D_ARRAY + UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = C.GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY + UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = C.GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE + UNSIGNED_INT_SAMPLER_2D_RECT = C.GL_UNSIGNED_INT_SAMPLER_2D_RECT + UNSIGNED_INT_SAMPLER_2D = C.GL_UNSIGNED_INT_SAMPLER_2D + UNSIGNED_INT_SAMPLER_3D = C.GL_UNSIGNED_INT_SAMPLER_3D + UNSIGNED_INT_SAMPLER_BUFFER = C.GL_UNSIGNED_INT_SAMPLER_BUFFER + UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY = C.GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY + UNSIGNED_INT_SAMPLER_CUBE = C.GL_UNSIGNED_INT_SAMPLER_CUBE + UNSIGNED_INT_VEC2 = C.GL_UNSIGNED_INT_VEC2 + UNSIGNED_INT_VEC3 = C.GL_UNSIGNED_INT_VEC3 + UNSIGNED_INT_VEC4 = C.GL_UNSIGNED_INT_VEC4 + UNSIGNED_INT = C.GL_UNSIGNED_INT + UNSIGNED_NORMALIZED = C.GL_UNSIGNED_NORMALIZED + UNSIGNED_SHORT_1_5_5_5_REV = C.GL_UNSIGNED_SHORT_1_5_5_5_REV + UNSIGNED_SHORT_4_4_4_4_REV = C.GL_UNSIGNED_SHORT_4_4_4_4_REV + UNSIGNED_SHORT_4_4_4_4 = C.GL_UNSIGNED_SHORT_4_4_4_4 + UNSIGNED_SHORT_5_5_5_1 = C.GL_UNSIGNED_SHORT_5_5_5_1 + UNSIGNED_SHORT_5_6_5_REV = C.GL_UNSIGNED_SHORT_5_6_5_REV + UNSIGNED_SHORT_5_6_5 = C.GL_UNSIGNED_SHORT_5_6_5 + UNSIGNED_SHORT = C.GL_UNSIGNED_SHORT + UPPER_LEFT = C.GL_UPPER_LEFT + V2F = C.GL_V2F + V3F = C.GL_V3F + VALIDATE_STATUS = C.GL_VALIDATE_STATUS + VENDOR = C.GL_VENDOR + VERSION_1_1 = C.GL_VERSION_1_1 + VERSION_1_2 = C.GL_VERSION_1_2 + VERSION_1_3 = C.GL_VERSION_1_3 + VERSION_1_4 = C.GL_VERSION_1_4 + VERSION_1_5 = C.GL_VERSION_1_5 + VERSION_2_0 = C.GL_VERSION_2_0 + VERSION_2_1 = C.GL_VERSION_2_1 + VERSION_3_0 = C.GL_VERSION_3_0 + VERSION_3_1 = C.GL_VERSION_3_1 + VERSION_3_2 = C.GL_VERSION_3_2 + VERSION = C.GL_VERSION + VERTEX_ARRAY_BINDING = C.GL_VERTEX_ARRAY_BINDING + VERTEX_ARRAY_BUFFER_BINDING = C.GL_VERTEX_ARRAY_BUFFER_BINDING + VERTEX_ARRAY_POINTER = C.GL_VERTEX_ARRAY_POINTER + VERTEX_ARRAY_SIZE = C.GL_VERTEX_ARRAY_SIZE + VERTEX_ARRAY_STRIDE = C.GL_VERTEX_ARRAY_STRIDE + VERTEX_ARRAY_TYPE = C.GL_VERTEX_ARRAY_TYPE + VERTEX_ARRAY = C.GL_VERTEX_ARRAY + VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = C.GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING + VERTEX_ATTRIB_ARRAY_ENABLED = C.GL_VERTEX_ATTRIB_ARRAY_ENABLED + VERTEX_ATTRIB_ARRAY_INTEGER = C.GL_VERTEX_ATTRIB_ARRAY_INTEGER + VERTEX_ATTRIB_ARRAY_NORMALIZED = C.GL_VERTEX_ATTRIB_ARRAY_NORMALIZED + VERTEX_ATTRIB_ARRAY_POINTER = C.GL_VERTEX_ATTRIB_ARRAY_POINTER + VERTEX_ATTRIB_ARRAY_SIZE = C.GL_VERTEX_ATTRIB_ARRAY_SIZE + VERTEX_ATTRIB_ARRAY_STRIDE = C.GL_VERTEX_ATTRIB_ARRAY_STRIDE + VERTEX_ATTRIB_ARRAY_TYPE = C.GL_VERTEX_ATTRIB_ARRAY_TYPE + VERTEX_PROGRAM_POINT_SIZE = C.GL_VERTEX_PROGRAM_POINT_SIZE + VERTEX_PROGRAM_TWO_SIDE = C.GL_VERTEX_PROGRAM_TWO_SIDE + VERTEX_SHADER = C.GL_VERTEX_SHADER + VIEWPORT_BIT = C.GL_VIEWPORT_BIT + VIEWPORT = C.GL_VIEWPORT + WAIT_FAILED = C.GL_WAIT_FAILED + WEIGHT_ARRAY_BUFFER_BINDING = C.GL_WEIGHT_ARRAY_BUFFER_BINDING + WRITE_ONLY = C.GL_WRITE_ONLY + XOR = C.GL_XOR + ZERO = C.GL_ZERO + ZOOM_X = C.GL_ZOOM_X + ZOOM_Y = C.GL_ZOOM_Y +) diff --git a/vendor/github.com/go-gl-legacy/gl/matrix.go b/vendor/github.com/go-gl-legacy/gl/matrix.go new file mode 100644 index 0000000..735fece --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/matrix.go @@ -0,0 +1,88 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" + +//void glFrustum (float64 left, float64 right, float64 bottom, float64 top, float64 zNear, float64 zFar) +func Frustum(left float64, right float64, bottom float64, top float64, zNear float64, zFar float64) { + C.glFrustum(C.GLdouble(left), C.GLdouble(right), C.GLdouble(bottom), C.GLdouble(top), C.GLdouble(zNear), C.GLdouble(zFar)) +} + +//void glLoadIdentity (void) +func LoadIdentity() { + C.glLoadIdentity() +} + +//void glLoadMatrixd (const float64 *m) +func LoadMatrixd(m *[16]float64) { + C.glLoadMatrixd((*C.GLdouble)(&m[0])) +} + +//void glLoadMatrixf (const float32 *m) +func LoadMatrixf(m *[16]float32) { + C.glLoadMatrixf((*C.GLfloat)(&m[0])) +} + +//void glMatrixMode (GLenum mode) +func MatrixMode(mode GLenum) { + C.glMatrixMode(C.GLenum(mode)) +} + +//void glMultMatrixd (const float64 *m) +func MultMatrixd(m *[16]float64) { + C.glMultMatrixd((*C.GLdouble)(&m[0])) +} + +//void glMultMatrixf (const float32 *m) +func MultMatrixf(m *[16]float32) { + C.glMultMatrixf((*C.GLfloat)(&m[0])) +} + +//void glOrtho (float64 left, float64 right, float64 bottom, float64 top, float64 zNear, float64 zFar) +func Ortho(left float64, right float64, bottom float64, top float64, zNear float64, zFar float64) { + C.glOrtho(C.GLdouble(left), C.GLdouble(right), C.GLdouble(bottom), C.GLdouble(top), C.GLdouble(zNear), C.GLdouble(zFar)) +} + +//void glPopMatrix (void) +func PopMatrix() { + C.glPopMatrix() +} + +//void glPushMatrix (void) +func PushMatrix() { + C.glPushMatrix() +} + +//void glRotated (float64 angle, float64 x, float64 y, float64 z) +func Rotated(angle float64, x float64, y float64, z float64) { + C.glRotated(C.GLdouble(angle), C.GLdouble(x), C.GLdouble(y), C.GLdouble(z)) +} + +//void glRotatef (float32 angle, float32 x, float32 y, float32 z) +func Rotatef(angle float32, x float32, y float32, z float32) { + C.glRotatef(C.GLfloat(angle), C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) +} + +//void glScaled (float64 x, float64 y, float64 z) +func Scaled(x float64, y float64, z float64) { + C.glScaled(C.GLdouble(x), C.GLdouble(y), C.GLdouble(z)) +} + +//void glScalef (float32 x, float32 y, float32 z) +func Scalef(x float32, y float32, z float32) { + C.glScalef(C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) +} + +//void glTranslated (float64 x, float64 y, float64 z) +func Translated(x float64, y float64, z float64) { + C.glTranslated(C.GLdouble(x), C.GLdouble(y), C.GLdouble(z)) +} + +//void glTranslatef (float32 x, float32 y, float32 z) +func Translatef(x float32, y float32, z float32) { + C.glTranslatef(C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) +} diff --git a/vendor/github.com/go-gl-legacy/gl/object.go b/vendor/github.com/go-gl-legacy/gl/object.go new file mode 100644 index 0000000..9d7fd4e --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/object.go @@ -0,0 +1,26 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" + +// Object + +type Object C.GLuint + +func (object Object) IsBuffer() bool { return C.glIsBuffer(C.GLuint(object)) != 0 } + +func (object Object) IsProgram() bool { return C.glIsProgram(C.GLuint(object)) != 0 } + +func (object Object) IsQuery() bool { return C.glIsQuery(C.GLuint(object)) != 0 } + +func (object Object) IsShader() bool { return C.glIsShader(C.GLuint(object)) != 0 } + +func (object Object) IsTexture() bool { return C.glIsTexture(C.GLuint(object)) != 0 } + +func (object Object) IsTransformFeedback() bool { return C.glIsTransformFeedback(C.GLuint(object)) != 0 } + +func (object Object) IsVertexArray() bool { return C.glIsVertexArray(C.GLuint(object)) != 0 } diff --git a/vendor/github.com/go-gl-legacy/gl/program.go b/vendor/github.com/go-gl-legacy/gl/program.go new file mode 100644 index 0000000..4bcd1c1 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/program.go @@ -0,0 +1,207 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +// GLuint workaroundGlGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) { +// return glGetUniformBlockIndex(program, uniformBlockName); +// } +import "C" +import "unsafe" + +// Program + +type Program Object + +func CreateProgram() Program { return Program(C.glCreateProgram()) } + +func (program Program) Delete() { C.glDeleteProgram(C.GLuint(program)) } + +func (program Program) AttachShader(shader Shader) { + C.glAttachShader(C.GLuint(program), C.GLuint(shader)) +} + +func (program Program) GetAttachedShaders() []Object { + var len C.GLint + C.glGetProgramiv(C.GLuint(program), C.GLenum(ACTIVE_UNIFORM_MAX_LENGTH), &len) + + objects := make([]Object, len) + C.glGetAttachedShaders(C.GLuint(program), C.GLsizei(len), nil, *((**C.GLuint)(unsafe.Pointer(&objects)))) + return objects +} + +func (program Program) DetachShader(shader Shader) { + C.glDetachShader(C.GLuint(program), C.GLuint(shader)) +} + +func (program Program) TransformFeedbackVaryings(names []string, buffer_mode GLenum) { + if len(names) == 0 { + C.glTransformFeedbackVaryings(C.GLuint(program), 0, (**C.GLchar)(nil), C.GLenum(buffer_mode)) + } else { + gl_names := make([]*C.GLchar, len(names)) + + for i := range names { + gl_names[i] = glString(names[i]) + } + + C.glTransformFeedbackVaryings(C.GLuint(program), C.GLsizei(len(gl_names)), &gl_names[0], C.GLenum(buffer_mode)) + + for _, s := range gl_names { + freeString(s) + } + } +} + +func (program Program) Link() { C.glLinkProgram(C.GLuint(program)) } + +func (program Program) Validate() { C.glValidateProgram(C.GLuint(program)) } + +func (program Program) Use() { C.glUseProgram(C.GLuint(program)) } + +func (program Program) Unuse() { C.glUseProgram(C.GLuint(0)) } + +// Deprecated, please use program.Unuse() +func ProgramUnuse() { C.glUseProgram(C.GLuint(0)) } + +func (program Program) GetInfoLog() string { + var length C.GLint + C.glGetProgramiv(C.GLuint(program), C.GLenum(INFO_LOG_LENGTH), &length) + // length is buffer size including null character + + if length > 1 { + log := C.malloc(C.size_t(length)) + defer C.free(log) + C.glGetProgramInfoLog(C.GLuint(program), C.GLsizei(length), nil, (*C.GLchar)(log)) + return C.GoString((*C.char)(log)) + } + return "" + +} + +func (program Program) Get(param GLenum) int { + var rv C.GLint + + C.glGetProgramiv(C.GLuint(program), C.GLenum(param), &rv) + return int(rv) +} + +// glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +func (program Program) GetActiveUniform(index int) ( + Size int, Type GLenum, Name string) { + // Maximum length of active uniform name in program + bufSize := program.Get(ACTIVE_UNIFORM_MAX_LENGTH) + nameBuf := C.malloc(C.size_t(bufSize)) + defer C.free(nameBuf) + var size C.GLint + C.glGetActiveUniform( + C.GLuint(program), + C.GLuint(index), + C.GLsizei(bufSize), + nil, // length == len(Name) + &size, + (*C.GLenum)(&Type), + (*C.GLchar)(nameBuf)) + Name = C.GoString((*C.char)(nameBuf)) + Size = int(size) + return +} + +func (program Program) GetUniformiv(location UniformLocation, values []int32) { + if len(values) == 0 { + panic("Invalid values length") + } + // FIXME(jimt): This should really yield only one return value instead of using a slice. + // http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml + C.glGetUniformiv(C.GLuint(program), C.GLint(location), (*C.GLint)(&(values[0]))) +} + +func (program Program) GetUniformfv(location UniformLocation, values []float32) { + if len(values) == 0 { + panic("Invalid values length") + } + // FIXME(jimt): This should really yield only one return value instead of using a slice. + // http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml + C.glGetUniformfv(C.GLuint(program), C.GLint(location), (*C.GLfloat)(&(values[0]))) +} + +func (program Program) GetUniformLocation(name string) UniformLocation { + + cname := glString(name) + defer freeString(cname) + + return UniformLocation(C.glGetUniformLocation(C.GLuint(program), cname)) +} + +func (program Program) GetUniformBlockIndex(name string) UniformBlockIndex { + + cname := glString(name) + defer freeString(cname) + + // Workaround bug in GLEW < 1.8 where glGetUniformBlockIndex expects + // a string of char instead of a string of GLchar. We could ask everybody + // to bump their version of GLEW, or we could add a bit of C code that + // will silently cast GLchar into char. + + //return UniformBlockIndex(C.glGetUniformBlockIndex(C.GLuint(program), cname)) + return UniformBlockIndex(C.workaroundGlGetUniformBlockIndex(C.GLuint(program), cname)) +} + +func (program Program) UniformBlockBinding(index UniformBlockIndex, binding uint) { + C.glUniformBlockBinding(C.GLuint(program), C.GLuint(index), C.GLuint(binding)) +} + +// glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +func (program Program) GetActiveAttrib(index int) ( + Size int, Type GLenum, Name string) { + // Maximum length of active uniform name in program + bufSize := program.Get(ACTIVE_ATTRIBUTE_MAX_LENGTH) + nameBuf := C.malloc(C.size_t(bufSize)) + defer C.free(nameBuf) + var size C.GLint + C.glGetActiveAttrib( + C.GLuint(program), + C.GLuint(index), + C.GLsizei(bufSize), + nil, // length == len(Name) + &size, + (*C.GLenum)(&Type), + (*C.GLchar)(nameBuf)) + Name = C.GoString((*C.char)(nameBuf)) + Size = int(size) + return +} + +func (program Program) GetAttribLocation(name string) AttribLocation { + + cname := glString(name) + defer freeString(cname) + + return AttribLocation(C.glGetAttribLocation(C.GLuint(program), cname)) +} + +func (program Program) BindAttribLocation(index AttribLocation, name string) { + + cname := glString(name) + defer freeString(cname) + + C.glBindAttribLocation(C.GLuint(program), C.GLuint(index), cname) + +} + +func (program Program) BindFragDataLocation(colorNumber int, name string) { + + cname := glString(name) + defer freeString(cname) + + C.glBindFragDataLocation(C.GLuint(program), C.GLuint(colorNumber), cname) +} + +func (program Program) GetFragDataLocation(name string) int { + + cname := glString(name) + defer freeString(cname) + + return int(C.glGetFragDataLocation(C.GLuint(program), cname)) +} diff --git a/vendor/github.com/go-gl-legacy/gl/query.go b/vendor/github.com/go-gl-legacy/gl/query.go new file mode 100644 index 0000000..88bdc32 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/query.go @@ -0,0 +1,96 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" + +type Query Object + +func GenQuery() (q Query) { + C.glGenQueries(1, (*C.GLuint)(&q)) + return +} + +func GenQueries(queries []Query) { + if len(queries) > 0 { + C.glGenQueries(C.GLsizei(len(queries)), (*C.GLuint)(&queries[0])) + } +} + +func (query Query) Begin(target GLenum) { + C.glBeginQuery(C.GLenum(target), C.GLuint(query)) +} + +func (query Query) BeginIndexed(target GLenum, index uint) { + C.glBeginQueryIndexed(C.GLenum(target), C.GLuint(index), C.GLuint(query)) +} + +func (query Query) Delete() { + C.glDeleteQueries(1, (*C.GLuint)(&query)) +} + +func (query Query) GetObjecti(pname GLenum) (param int32) { + C.glGetQueryObjectiv(C.GLuint(query), C.GLenum(pname), (*C.GLint)(¶m)) + return +} + +func (query Query) GetObjectui(pname GLenum) (param uint32) { + C.glGetQueryObjectuiv(C.GLuint(query), C.GLenum(pname), (*C.GLuint)(¶m)) + return +} + +func (query Query) GetObjecti64(pname GLenum) (param int64) { + C.glGetQueryObjecti64v(C.GLuint(query), C.GLenum(pname), (*C.GLint64)(¶m)) + return +} + +func (query Query) GetObjectui64(pname GLenum) (param uint64) { + C.glGetQueryObjectui64v(C.GLuint(query), C.GLenum(pname), (*C.GLuint64)(¶m)) + return +} + +func (query Query) Counter(target GLenum) { + C.glQueryCounter(C.GLuint(query), C.GLenum(target)) +} + +// Returns whether the passed samples counter is immediately available. If a delay +// would not occur waiting for the query result, true is returned, which also indicates +// that the results of all previous queries are available as well. +func (query Query) ResultAvailable() bool { + return query.GetObjectui(QUERY_RESULT_AVAILABLE) == TRUE +} + +func (query Query) BeginConditionalRender(mode GLenum) { + C.glBeginConditionalRender(C.GLuint(query), C.GLenum(mode)) +} + +func DeleteQueries(queries []Query) { + if len(queries) > 0 { + C.glDeleteQueries(C.GLsizei(len(queries)), (*C.GLuint)(&queries[0])) + } +} + +func EndQuery(target GLenum) { + C.glEndQuery(C.GLenum(target)) +} + +func GetQuery(target GLenum, pname GLenum) (param int32) { + C.glGetQueryiv(C.GLenum(target), C.GLenum(pname), (*C.GLint)(¶m)) + return +} + +func GetQueryIndexed(target GLenum, index uint, pname GLenum) (param int32) { + C.glGetQueryIndexediv(C.GLenum(target), C.GLuint(index), C.GLenum(pname), (*C.GLint)(¶m)) + return +} + +func (query Query) EndQueryIndexed(target GLenum, index uint) { + C.glEndQueryIndexed(C.GLenum(target), C.GLuint(index)) +} + +func (query Query) EndConditionalRender() { + C.glEndConditionalRender() +} diff --git a/vendor/github.com/go-gl-legacy/gl/renderbuffer.go b/vendor/github.com/go-gl-legacy/gl/renderbuffer.go new file mode 100644 index 0000000..84431e6 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/renderbuffer.go @@ -0,0 +1,72 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" + +// Renderbuffer Objects + +type Renderbuffer Object + +// void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) +func GenRenderbuffer() Renderbuffer { + var b C.GLuint + C.glGenRenderbuffers(1, &b) + return Renderbuffer(b) +} + +// Fill slice with new renderbuffers +func GenRenderbuffers(bufs []Renderbuffer) { + if len(bufs) > 0 { + C.glGenRenderbuffers(C.GLsizei(len(bufs)), (*C.GLuint)(&bufs[0])) + } +} + +// void glBindRenderbuffer(GLenum target, GLuint renderbuffer); +func (rb Renderbuffer) Bind() { + C.glBindRenderbuffer(C.GLenum(RENDERBUFFER), C.GLuint(rb)) +} + +// Unbind this texture +func (rb Renderbuffer) Unbind() { + C.glBindRenderbuffer(C.GLenum(RENDERBUFFER), 0) +} + +// void glDeleteRenderbuffers(GLsizei n, GLuint* renderbuffers); +func (rb Renderbuffer) Delete() { + C.glDeleteRenderbuffers(1, (*C.GLuint)(&rb)) +} + +func DeleteRenderbuffers(bufs []Renderbuffer) { + if len(bufs) > 0 { + C.glDeleteRenderbuffers(C.GLsizei(len(bufs)), (*C.GLuint)(&bufs[0])) + } +} + +// void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params); +func GetRenderbufferParameteriv(target, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params size") + } + + C.glGetRenderbufferParameteriv(C.GLenum(target), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +// void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +func RenderbufferStorage(target, internalformat GLenum, width int, height int) { + C.glRenderbufferStorage(C.GLenum(target), C.GLenum(internalformat), C.GLsizei(width), C.GLsizei(height)) +} + +// void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +func RenderbufferStorageMultisample(target GLenum, samples int, internalformat GLenum, width, height int) { + C.glRenderbufferStorageMultisample(C.GLenum(target), C.GLsizei(samples), C.GLenum(internalformat), C.GLsizei(width), C.GLsizei(height)) +} + +// GLsync glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +func (rb Renderbuffer) FramebufferRenderbuffer(target, attachment, renderbuffertarget GLenum) /* GLsync */ { + // TODO: sync stuff. return (GLsync)(C.glFramebufferRenderbuffer (C.GLenum(target), C.GLenum(attachment), C.GLenum(renderbuffertarget), C.GLuint(rb))) + C.glFramebufferRenderbuffer(C.GLenum(target), C.GLenum(attachment), C.GLenum(renderbuffertarget), C.GLuint(rb)) +} diff --git a/vendor/github.com/go-gl-legacy/gl/shader.go b/vendor/github.com/go-gl-legacy/gl/shader.go new file mode 100644 index 0000000..cd8514f --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/shader.go @@ -0,0 +1,79 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +// +// // Workaround for https://github.com/go-gl/gl/issues/104 +// void gogl_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* len, GLchar* source) { +// glGetShaderSource(shader, bufsize, len, source); +// } +// +import "C" +import "unsafe" + +// Shader + +type Shader Object + +func CreateShader(type_ GLenum) Shader { return Shader(C.glCreateShader(C.GLenum(type_))) } + +func (shader Shader) Delete() { C.glDeleteShader(C.GLuint(shader)) } + +func (shader Shader) GetInfoLog() string { + var length C.GLint + C.glGetShaderiv(C.GLuint(shader), C.GLenum(INFO_LOG_LENGTH), &length) + // length is buffer size including null character + + if length > 1 { + log := C.malloc(C.size_t(length)) + defer C.free(log) + C.glGetShaderInfoLog(C.GLuint(shader), C.GLsizei(length), nil, (*C.GLchar)(log)) + return C.GoString((*C.char)(log)) + } + return "" +} + +func (shader Shader) GetSource() string { + var length C.GLint + C.glGetShaderiv(C.GLuint(shader), C.GLenum(SHADER_SOURCE_LENGTH), &length) + + log := C.malloc(C.size_t(length + 1)) + C.gogl_glGetShaderSource(C.GLuint(shader), C.GLsizei(length), nil, (*C.GLchar)(log)) + + defer C.free(log) + + if length > 1 { + log := C.malloc(C.size_t(length + 1)) + defer C.free(log) + C.gogl_glGetShaderSource(C.GLuint(shader), C.GLsizei(length), nil, (*C.GLchar)(log)) + return C.GoString((*C.char)(log)) + } + return "" +} + +func (shader Shader) Source(source ...string) { + count := C.GLsizei(len(source)) + cstrings := make([]*C.GLchar, count) + length := make([]C.GLint, count) + + for i, s := range source { + csource := glString(s) + cstrings[i] = csource + length[i] = C.GLint(len(s)) + defer freeString(csource) + } + + C.glShaderSource(C.GLuint(shader), count, (**_Ctype_GLchar)(unsafe.Pointer(&cstrings[0])), (*_Ctype_GLint)(unsafe.Pointer(&length[0]))) +} + +func (shader Shader) Compile() { C.glCompileShader(C.GLuint(shader)) } + +func (shader Shader) Get(param GLenum) int { + var rv C.GLint + + C.glGetShaderiv(C.GLuint(shader), C.GLenum(param), &rv) + return int(rv) +} diff --git a/vendor/github.com/go-gl-legacy/gl/texture.go b/vendor/github.com/go-gl-legacy/gl/texture.go new file mode 100644 index 0000000..0d17926 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/texture.go @@ -0,0 +1,516 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" +import "unsafe" + +//bool glAreTexturesResident (GLsizei n, const uint *textures, bool *residences) +func AreTexturesResident(textures []uint, residences []bool) bool { + sz := len(textures) + if sz == 0 { + return false + } + + if sz != len(residences) { + panic("Residences slice must be equal in length to textures slice.") + } + + ret := C.glAreTexturesResident( + C.GLsizei(sz), + (*C.GLuint)(unsafe.Pointer(&textures[0])), + (*C.GLboolean)(unsafe.Pointer(&residences[0])), + ) + + if ret == TRUE { + return true + } + + return false +} + +func ActiveTexture(texture GLenum) { C.glActiveTexture(C.GLenum(texture)) } + +// Texture + +type Texture Object + +// Create single texture object +func GenTexture() Texture { + var b C.GLuint + C.glGenTextures(1, &b) + return Texture(b) +} + +// Fill slice with new textures +func GenTextures(textures []Texture) { + if len(textures) > 0 { + C.glGenTextures(C.GLsizei(len(textures)), (*C.GLuint)(&textures[0])) + } +} + +// Delete texture object +func (texture Texture) Delete() { + b := C.GLuint(texture) + C.glDeleteTextures(1, &b) +} + +// Delete all textures in slice +func DeleteTextures(textures []Texture) { + if len(textures) > 0 { + C.glDeleteTextures(C.GLsizei(len(textures)), (*C.GLuint)(&textures[0])) + } +} + +// Bind this texture as target +func (texture Texture) Bind(target GLenum) { + C.glBindTexture(C.GLenum(target), C.GLuint(texture)) +} + +// Unbind this texture +func (texture Texture) Unbind(target GLenum) { + C.glBindTexture(C.GLenum(target), 0) +} + +//void glTexImage1D (GLenum target, int level, int internalformat, int width, int border, GLenum format, GLenum type, const GLvoid *pixels) +func TexImage1D(target GLenum, level int, internalformat int, width int, border int, format, typ GLenum, pixels interface{}) { + C.glTexImage1D(C.GLenum(target), C.GLint(level), C.GLint(internalformat), + C.GLsizei(width), C.GLint(border), C.GLenum(format), C.GLenum(typ), + ptr(pixels)) +} + +//void glTexImage2D (GLenum target, int level, int internalformat, int width, int height, int border, GLenum format, GLenum type, const GLvoid *pixels) +func TexImage2D(target GLenum, level int, internalformat int, width int, height int, border int, format, typ GLenum, pixels interface{}) { + C.glTexImage2D(C.GLenum(target), C.GLint(level), C.GLint(internalformat), + C.GLsizei(width), C.GLsizei(height), C.GLint(border), C.GLenum(format), + C.GLenum(typ), ptr(pixels)) +} + +//void glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat, GLsizei width, +// GLsizei height, GLint border, GLsizei imagesize, const GLvoid * data ) +func CompressedTexImage2D(target GLenum, level int, internalformat GLenum, width int, height int, border int, imagesize int, data interface{}) { + C.glCompressedTexImage2D(C.GLenum(target), C.GLint(level), C.GLenum(internalformat), + C.GLsizei(width), C.GLsizei(height), C.GLint(border), C.GLsizei(imagesize), ptr(data)) +} + +//void glGetCompressedTexImage( GLenum target, GLint lod, GLvoid *img ) +func GetCompressedTexImage(target GLenum, lod int, data interface{}) { + C.glGetCompressedTexImage(C.GLenum(target), C.GLint(lod), ptr(data)) +} + +//void glTexImage3D (GLenum target, int level, int internalformat, int width, int height, int depth, int border, GLenum format, GLenum type, const GLvoid *pixels) +func TexImage3D(target GLenum, level int, internalformat int, width, height, depth int, border int, format, typ GLenum, pixels interface{}) { + C.glTexImage3D(C.GLenum(target), C.GLint(level), C.GLint(internalformat), + C.GLsizei(width), C.GLsizei(height), C.GLsizei(depth), C.GLint(border), + C.GLenum(format), C.GLenum(typ), ptr(pixels)) +} + +//void glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer) +func TexBuffer(target, internalformat GLenum, buffer Buffer) { + C.glTexBuffer(C.GLenum(target), C.GLenum(internalformat), C.GLuint(buffer)) +} + +//void glPixelMapfv (GLenum map, int mapsize, const float *values) +func PixelMapfv(map_ GLenum, mapsize int, values *float32) { + C.glPixelMapfv(C.GLenum(map_), C.GLsizei(mapsize), (*C.GLfloat)(values)) +} + +//void glPixelMapuiv (GLenum map, int mapsize, const uint *values) +func PixelMapuiv(map_ GLenum, mapsize int, values *uint32) { + C.glPixelMapuiv(C.GLenum(map_), C.GLsizei(mapsize), (*C.GLuint)(values)) +} + +//void glPixelMapusv (GLenum map, int mapsize, const uint16 *values) +func PixelMapusv(map_ GLenum, mapsize int, values *uint16) { + C.glPixelMapusv(C.GLenum(map_), C.GLsizei(mapsize), (*C.GLushort)(values)) +} + +//void glTexSubImage1D (GLenum target, int level, int xoffset, int width, GLenum format, GLenum type, const GLvoid *pixels) +func TexSubImage1D(target GLenum, level int, xoffset int, width int, format, typ GLenum, pixels interface{}) { + C.glTexSubImage1D(C.GLenum(target), C.GLint(level), C.GLint(xoffset), + C.GLsizei(width), C.GLenum(format), C.GLenum(typ), ptr(pixels)) +} + +//void glTexSubImage2D (GLenum target, int level, int xoffset, int yoffset, int width, int height, GLenum format, GLenum type, const GLvoid *pixels) +func TexSubImage2D(target GLenum, level int, xoffset int, yoffset int, width int, height int, format, typ GLenum, pixels interface{}) { + C.glTexSubImage2D(C.GLenum(target), C.GLint(level), C.GLint(xoffset), + C.GLint(yoffset), C.GLsizei(width), C.GLsizei(height), C.GLenum(format), + C.GLenum(typ), ptr(pixels)) +} + +//void glTexImage3D (GLenum target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, GLenum format, GLenum type, const GLvoid *pixels) +func TexSubImage3D(target GLenum, level int, xoffset, yoffset, zoffset, width, height, depth int, format, typ GLenum, pixels interface{}) { + C.glTexSubImage3D(C.GLenum(target), C.GLint(level), + C.GLint(xoffset), C.GLint(yoffset), C.GLint(zoffset), + C.GLsizei(width), C.GLsizei(height), C.GLsizei(depth), + C.GLenum(format), C.GLenum(typ), ptr(pixels)) +} + +//void glCopyTexImage1D (GLenum target, int level, GLenum internalFormat, int x, int y, int width, int border) +func CopyTexImage1D(target GLenum, level int, internalFormat GLenum, x int, y int, width int, border int) { + C.glCopyTexImage1D(C.GLenum(target), C.GLint(level), C.GLenum(internalFormat), C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLint(border)) +} + +//void glCopyTexImage2D (GLenum target, int level, GLenum internalFormat, int x, int y, int width, int height, int border) +func CopyTexImage2D(target GLenum, level int, internalFormat GLenum, x int, y int, width int, height int, border int) { + C.glCopyTexImage2D(C.GLenum(target), C.GLint(level), C.GLenum(internalFormat), C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height), C.GLint(border)) +} + +//void glCopyTexSubImage1D (GLenum target, int level, int xoffset, int x, int y, int width) +func CopyTexSubImage1D(target GLenum, level int, xoffset int, x int, y int, width int) { + C.glCopyTexSubImage1D(C.GLenum(target), C.GLint(level), C.GLint(xoffset), C.GLint(x), C.GLint(y), C.GLsizei(width)) +} + +//void glCopyTexSubImage2D (GLenum target, int level, int xoffset, int yoffset, int x, int y, int width, int height) +func CopyTexSubImage2D(target GLenum, level int, xoffset int, yoffset int, x int, y int, width int, height int) { + C.glCopyTexSubImage2D(C.GLenum(target), C.GLint(level), C.GLint(xoffset), C.GLint(yoffset), C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height)) +} + +// TODO 3D textures + +//void glTexEnvf (GLenum target, GLenum pname, float32 param) +func TexEnvf(target GLenum, pname GLenum, param float32) { + C.glTexEnvf(C.GLenum(target), C.GLenum(pname), C.GLfloat(param)) +} + +//void glTexEnvfv (GLenum target, GLenum pname, const float *params) +func TexEnvfv(target GLenum, pname GLenum, params []float32) { + if len(params) != 1 && len(params) != 4 { + panic("Invalid params slice length") + } + C.glTexEnvfv(C.GLenum(target), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glTexEnvi (GLenum target, GLenum pname, int param) +func TexEnvi(target GLenum, pname GLenum, param int) { + C.glTexEnvi(C.GLenum(target), C.GLenum(pname), C.GLint(param)) +} + +//void glTexEnviv (GLenum target, GLenum pname, const int *params) +func TexEnviv(target GLenum, pname GLenum, params []int32) { + if len(params) != 1 && len(params) != 4 { + panic("Invalid params slice length") + } + C.glTexEnviv(C.GLenum(target), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glTexGend (GLenum coord, GLenum pname, float64 param) +func TexGend(coord GLenum, pname GLenum, param float64) { + C.glTexGend(C.GLenum(coord), C.GLenum(pname), C.GLdouble(param)) +} + +//void glTexGendv (GLenum coord, GLenum pname, const float64 *params) +func TexGendv(coord GLenum, pname GLenum, params []float64) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glTexGendv(C.GLenum(coord), C.GLenum(pname), (*C.GLdouble)(¶ms[0])) +} + +//void glTexGenf (GLenum coord, GLenum pname, float32 param) +func TexGenf(coord GLenum, pname GLenum, param float32) { + C.glTexGenf(C.GLenum(coord), C.GLenum(pname), C.GLfloat(param)) +} + +//void glTexGenfv (GLenum coord, GLenum pname, const float *params) +func TexGenfv(coord GLenum, pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glTexGenfv(C.GLenum(coord), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glTexGeni (GLenum coord, GLenum pname, int param) +func TexGeni(coord GLenum, pname GLenum, param int) { + C.glTexGeni(C.GLenum(coord), C.GLenum(pname), C.GLint(param)) +} + +//void glTexGeniv (GLenum coord, GLenum pname, const int *params) +func TexGeniv(coord GLenum, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glTexGeniv(C.GLenum(coord), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glTexParameterf (GLenum target, GLenum pname, float32 param) +func TexParameterf(target GLenum, pname GLenum, param float32) { + C.glTexParameterf(C.GLenum(target), C.GLenum(pname), C.GLfloat(param)) +} + +//void glTexParameterfv (GLenum target, GLenum pname, const float *params) +func TexParameterfv(target GLenum, pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glTexParameterfv(C.GLenum(target), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glTexParameteri (GLenum target, GLenum pname, int param) +func TexParameteri(target GLenum, pname GLenum, param int) { + C.glTexParameteri(C.GLenum(target), C.GLenum(pname), C.GLint(param)) +} + +//void glTexParameteriv (GLenum target, GLenum pname, const int *params) +func TexParameteriv(target GLenum, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glTexParameteriv(C.GLenum(target), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glPrioritizeTextures (GLsizei n, const uint *textures, const GLclampf *priorities) +func PrioritizeTextures(n int, textures *uint32, priorities *GLclampf) { + C.glPrioritizeTextures(C.GLsizei(n), (*C.GLuint)(textures), (*C.GLclampf)(priorities)) +} + +//void glGetTexEnvfv (GLenum target, GLenum pname, float *params) +func GetTexEnvfv(target GLenum, pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glGetTexEnvfv(C.GLenum(target), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glGetTexEnviv (GLenum target, GLenum pname, int *params) +func GetTexEnviv(target GLenum, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glGetTexEnviv(C.GLenum(target), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glGetTexGendv (GLenum coord, GLenum pname, float64 *params) +func GetTexGendv(coord GLenum, pname GLenum, params []float64) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glGetTexGendv(C.GLenum(coord), C.GLenum(pname), (*C.GLdouble)(¶ms[0])) +} + +//void glGetTexGenfv (GLenum coord, GLenum pname, float *params) +func GetTexGenfv(coord GLenum, pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glGetTexGenfv(C.GLenum(coord), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glGetTexGeniv (GLenum coord, GLenum pname, int *params) +func GetTexGeniv(coord GLenum, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glGetTexGeniv(C.GLenum(coord), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glGetTexImage (GLenum target, int level, GLenum format, GLenum type, GLvoid *pixels) +func GetTexImage(target GLenum, level int, format, typ GLenum, pixels interface{}) { + C.glGetTexImage(C.GLenum(target), C.GLint(level), C.GLenum(format), + C.GLenum(typ), ptr(pixels)) +} + +//void glGetTexLevelParameterfv (GLenum target, int level, GLenum pname, float *params) +func GetTexLevelParameterfv(target GLenum, level int, pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glGetTexLevelParameterfv(C.GLenum(target), C.GLint(level), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glGetTexLevelParameteriv (GLenum target, int level, GLenum pname, int *params) +func GetTexLevelParameteriv(target GLenum, level int, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glGetTexLevelParameteriv(C.GLenum(target), C.GLint(level), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +//void glGetTexParameterfv (GLenum target, GLenum pname, float *params) +func GetTexParameterfv(target GLenum, pname GLenum, params []float32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glGetTexParameterfv(C.GLenum(target), C.GLenum(pname), (*C.GLfloat)(¶ms[0])) +} + +//void glGetTexParameteriv (GLenum target, GLenum pname, int *params) +func GetTexParameteriv(target GLenum, pname GLenum, params []int32) { + if len(params) == 0 { + panic("Invalid params slice length") + } + C.glGetTexParameteriv(C.GLenum(target), C.GLenum(pname), (*C.GLint)(¶ms[0])) +} + +func GenerateMipmap(target GLenum) { + C.glGenerateMipmap(C.GLenum(target)) +} + +//void glTexCoord1d (float64 s) +func TexCoord1d(s float64) { + C.glTexCoord1d(C.GLdouble(s)) +} + +//void glTexCoord1dv (const float64 *v) +func TexCoord1dv(v *[1]float64) { + C.glTexCoord1dv((*C.GLdouble)(&v[0])) +} + +//void glTexCoord1f (float32 s) +func TexCoord1f(s float32) { + C.glTexCoord1f(C.GLfloat(s)) +} + +//void glTexCoord1fv (const float *v) +func TexCoord1fv(v *[1]float32) { + C.glTexCoord1fv((*C.GLfloat)(&v[0])) +} + +//void glTexCoord1i (int s) +func TexCoord1i(s int) { + C.glTexCoord1i(C.GLint(s)) +} + +//void glTexCoord1iv (const int *v) +func TexCoord1iv(v *[1]int32) { + C.glTexCoord1iv((*C.GLint)(&v[0])) +} + +//void glTexCoord1s (int16 s) +func TexCoord1s(s int16) { + C.glTexCoord1s(C.GLshort(s)) +} + +//void glTexCoord1sv (const int16 *v) +func TexCoord1sv(v *[1]int16) { + C.glTexCoord1sv((*C.GLshort)(&v[0])) +} + +//void glTexCoord2d (float64 s, float64 t) +func TexCoord2d(s float64, t float64) { + C.glTexCoord2d(C.GLdouble(s), C.GLdouble(t)) +} + +//void glTexCoord2dv (const float64 *v) +func TexCoord2dv(v *[2]float64) { + C.glTexCoord2dv((*C.GLdouble)(&v[0])) +} + +//void glTexCoord2f (float32 s, float32 t) +func TexCoord2f(s float32, t float32) { + C.glTexCoord2f(C.GLfloat(s), C.GLfloat(t)) +} + +//void glTexCoord2fv (const float *v) +func TexCoord2fv(v *[2]float32) { + C.glTexCoord2fv((*C.GLfloat)(&v[0])) +} + +//void glTexCoord2i (int s, int t) +func TexCoord2i(s int, t int) { + C.glTexCoord2i(C.GLint(s), C.GLint(t)) +} + +//void glTexCoord2iv (const int *v) +func TexCoord2iv(v *[2]int32) { + C.glTexCoord2iv((*C.GLint)(&v[0])) +} + +//void glTexCoord2s (int16 s, int16 t) +func TexCoord2s(s int16, t int16) { + C.glTexCoord2s(C.GLshort(s), C.GLshort(t)) +} + +//void glTexCoord2sv (const int16 *v) +func TexCoord2sv(v *[2]int16) { + C.glTexCoord2sv((*C.GLshort)(&v[0])) +} + +//void glTexCoord3d (float64 s, float64 t, float64 r) +func TexCoord3d(s float64, t float64, r float64) { + C.glTexCoord3d(C.GLdouble(s), C.GLdouble(t), C.GLdouble(r)) +} + +//void glTexCoord3dv (const float64 *v) +func TexCoord3dv(v *[3]float64) { + C.glTexCoord3dv((*C.GLdouble)(&v[0])) +} + +//void glTexCoord3f (float32 s, float32 t, float32 r) +func TexCoord3f(s float32, t float32, r float32) { + C.glTexCoord3f(C.GLfloat(s), C.GLfloat(t), C.GLfloat(r)) +} + +//void glTexCoord3fv (const float *v) +func TexCoord3fv(v *[3]float32) { + C.glTexCoord3fv((*C.GLfloat)(&v[0])) +} + +//void glTexCoord3i (int s, int t, int r) +func TexCoord3i(s int, t int, r int) { + C.glTexCoord3i(C.GLint(s), C.GLint(t), C.GLint(r)) +} + +//void glTexCoord3iv (const int *v) +func TexCoord3iv(v *[3]int32) { + C.glTexCoord3iv((*C.GLint)(&v[0])) +} + +//void glTexCoord3s (int16 s, int16 t, int16 r) +func TexCoord3s(s int16, t int16, r int16) { + C.glTexCoord3s(C.GLshort(s), C.GLshort(t), C.GLshort(r)) +} + +//void glTexCoord3sv (const int16 *v) +func TexCoord3sv(v *[3]int16) { + C.glTexCoord3sv((*C.GLshort)(&v[0])) +} + +//void glTexCoord4d (float64 s, float64 t, float64 r, float64 q) +func TexCoord4d(s float64, t float64, r float64, q float64) { + C.glTexCoord4d(C.GLdouble(s), C.GLdouble(t), C.GLdouble(r), C.GLdouble(q)) +} + +//void glTexCoord4dv (const float64 *v) +func TexCoord4dv(v *[4]float64) { + C.glTexCoord4dv((*C.GLdouble)(&v[0])) +} + +//void glTexCoord4f (float32 s, float32 t, float32 r, float32 q) +func TexCoord4f(s float32, t float32, r float32, q float32) { + C.glTexCoord4f(C.GLfloat(s), C.GLfloat(t), C.GLfloat(r), C.GLfloat(q)) +} + +//void glTexCoord4fv (const float *v) +func TexCoord4fv(v *[4]float32) { + C.glTexCoord4fv((*C.GLfloat)(&v[0])) +} + +//void glTexCoord4i (int s, int t, int r, int q) +func TexCoord4i(s int, t int, r int, q int) { + C.glTexCoord4i(C.GLint(s), C.GLint(t), C.GLint(r), C.GLint(q)) +} + +//void glTexCoord4iv (const int *v) +func TexCoord4iv(v *[4]int32) { + C.glTexCoord4iv((*C.GLint)(&v[0])) +} + +//void glTexCoord4s (int16 s, int16 t, int16 r, int16 q) +func TexCoord4s(s int16, t int16, r int16, q int16) { + C.glTexCoord4s(C.GLshort(s), C.GLshort(t), C.GLshort(r), C.GLshort(q)) +} + +//void glTexCoord4sv (const int16 *v) +func TexCoord4sv(v *[4]int16) { + C.glTexCoord4sv((*C.GLshort)(&v[0])) +} + +//void glTexCoordPointer (int size, GLenum type, int stride, const GLvoid *pointer) +func TexCoordPointer(size int, typ GLenum, stride int, pointer interface{}) { + C.glTexCoordPointer(C.GLint(size), C.GLenum(typ), C.GLsizei(stride), + ptr(pointer)) +} diff --git a/vendor/github.com/go-gl-legacy/gl/transformfeedback.go b/vendor/github.com/go-gl-legacy/gl/transformfeedback.go new file mode 100644 index 0000000..d1b51d4 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/transformfeedback.go @@ -0,0 +1,63 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" + +// Transform Feedback Objects + +type TransformFeedback Object + +// Create a single transform feedback object +func GenTransformFeedback() TransformFeedback { + var t C.GLuint + C.glGenTransformFeedbacks(1, &t) + return TransformFeedback(t) +} + +// Fill slice with new transform feedbacks +func GenTransformFeedbacks(feedbacks []TransformFeedback) { + if len(feedbacks) > 0 { + C.glGenTransformFeedbacks(C.GLsizei(len(feedbacks)), (*C.GLuint)(&feedbacks[0])) + } +} + +// Delete a transform feedback object +func (feedback TransformFeedback) Delete() { + C.glDeleteTransformFeedbacks(1, (*C.GLuint)(&feedback)) +} + +// Draw the results of the last Begin/End cycle from this transform feedback using primitive type 'mode' +func (feedback TransformFeedback) Draw(mode GLenum) { + C.glDrawTransformFeedback(C.GLenum(mode), C.GLuint(feedback)) +} + +// Delete all transform feedbacks in a slice +func DeleteTransformFeedbacks(feedbacks []TransformFeedback) { + if len(feedbacks) > 0 { + C.glDeleteTransformFeedbacks(C.GLsizei(len(feedbacks)), (*C.GLuint)(&feedbacks[0])) + } +} + +// Bind this transform feedback as target +func (feedback TransformFeedback) Bind(target GLenum) { + C.glBindTransformFeedback(C.GLenum(target), C.GLuint(feedback)) +} + +// Begin transform feedback with primitive type 'mode' +func BeginTransformFeedback(mode GLenum) { + C.glBeginTransformFeedback(C.GLenum(mode)) +} + +// Pause transform feedback +func PauseTransformFeedback() { + C.glPauseTransformFeedback() +} + +// End transform feedback +func EndTransformFeedback() { + C.glEndTransformFeedback() +} diff --git a/vendor/github.com/go-gl-legacy/gl/uniformblockindex.go b/vendor/github.com/go-gl-legacy/gl/uniformblockindex.go new file mode 100644 index 0000000..7855b3f --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/uniformblockindex.go @@ -0,0 +1,7 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +type UniformBlockIndex uint diff --git a/vendor/github.com/go-gl-legacy/gl/uniformlocation.go b/vendor/github.com/go-gl-legacy/gl/uniformlocation.go new file mode 100644 index 0000000..e041db3 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/uniformlocation.go @@ -0,0 +1,228 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" +import "unsafe" + +// UniformLocation +//TODO + +type UniformLocation int + +func (location UniformLocation) Uniform1f(x float32) { + C.glUniform1f(C.GLint(location), C.GLfloat(x)) +} + +func (location UniformLocation) Uniform2f(x float32, y float32) { + C.glUniform2f(C.GLint(location), C.GLfloat(x), C.GLfloat(y)) +} + +func (location UniformLocation) Uniform3f(x float32, y float32, z float32) { + C.glUniform3f(C.GLint(location), C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) +} + +func (location UniformLocation) Uniform1fv(count int, v []float32) { + if len(v) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniform1fv(C.GLint(location), C.GLsizei(count), (*C.GLfloat)(&v[0])) +} + +func (location UniformLocation) Uniform1i(x int) { + C.glUniform1i(C.GLint(location), C.GLint(x)) +} + +func (location UniformLocation) Uniform1iv(count int, v []int32) { + if len(v) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniform1iv(C.GLint(location), C.GLsizei(count), (*C.GLint)(&v[0])) +} + +func (location UniformLocation) Uniform2fv(count int, v []float32) { + if len(v) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniform2fv(C.GLint(location), C.GLsizei(count), (*C.GLfloat)(&v[0])) +} + +func (location UniformLocation) Uniform2i(x int, y int) { + C.glUniform2i(C.GLint(location), C.GLint(x), C.GLint(y)) +} + +func (location UniformLocation) Uniform2iv(count int, v []int32) { + if len(v) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniform2iv(C.GLint(location), C.GLsizei(count), (*C.GLint)(&v[0])) +} + +func (location UniformLocation) Uniform3fv(count int, v []float32) { + if len(v) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniform3fv(C.GLint(location), C.GLsizei(count), (*C.GLfloat)(&v[0])) +} + +func (location UniformLocation) Uniform3i(x int, y int, z int) { + C.glUniform3i(C.GLint(location), C.GLint(x), C.GLint(y), C.GLint(z)) +} + +func (location UniformLocation) Uniform3iv(count int, v []int32) { + if len(v) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniform3iv(C.GLint(location), C.GLsizei(count), (*C.GLint)(&v[0])) +} + +func (location UniformLocation) Uniform4f(x float32, y float32, z float32, w float32) { + C.glUniform4f(C.GLint(location), C.GLfloat(x), C.GLfloat(y), C.GLfloat(z), C.GLfloat(w)) +} + +func (location UniformLocation) Uniform4fv(count int, v []float32) { + if len(v) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniform4fv(C.GLint(location), C.GLsizei(count), (*C.GLfloat)(&v[0])) +} + +func (location UniformLocation) Uniform4i(x int, y int, z int, w int) { + C.glUniform4i(C.GLint(location), C.GLint(x), C.GLint(y), C.GLint(z), C.GLint(w)) +} + +func (location UniformLocation) Uniform4iv(count int, v []int32) { + if len(v) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniform4iv(C.GLint(location), C.GLsizei(count), (*C.GLint)(&v[0])) +} + +func (location UniformLocation) UniformMatrix2fv(transpose bool, list ...[4]float32) { + if len(list) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniformMatrix2fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) +} + +func (location UniformLocation) UniformMatrix2f(transpose bool, matrix *[4]float32) { + if matrix == nil { + panic("Matrix is nil") + } + C.glUniformMatrix2fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) +} + +func (location UniformLocation) UniformMatrix3fv(transpose bool, list ...[9]float32) { + if len(list) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniformMatrix3fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) +} + +func (location UniformLocation) UniformMatrix3f(transpose bool, matrix *[9]float32) { + if matrix == nil { + panic("Matrix is nil") + } + C.glUniformMatrix3fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) +} + +func (location UniformLocation) UniformMatrix4fv(transpose bool, list ...[16]float32) { + if len(list) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniformMatrix4fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) +} + +func (location UniformLocation) UniformMatrix4f(transpose bool, matrix *[16]float32) { + if matrix == nil { + panic("Matrix is nil") + } + C.glUniformMatrix4fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) +} + +func (location UniformLocation) UniformMatrix2x3fv(transpose bool, list ...[6]float32) { + if len(list) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniformMatrix2x3fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) +} + +func (location UniformLocation) UniformMatrix2x3f(transpose bool, matrix *[6]float32) { + if matrix == nil { + panic("Matrix is nil") + } + C.glUniformMatrix2x3fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) +} + +func (location UniformLocation) UniformMatrix3x2fv(transpose bool, list ...[6]float32) { + if len(list) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniformMatrix3x2fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) +} + +func (location UniformLocation) UniformMatrix3x2f(transpose bool, matrix *[6]float32) { + if matrix == nil { + panic("Matrix is nil") + } + C.glUniformMatrix3x2fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) +} + +func (location UniformLocation) UniformMatrix2x4fv(transpose bool, list ...[8]float32) { + if len(list) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniformMatrix2x4fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) +} + +func (location UniformLocation) UniformMatrix2x4f(transpose bool, matrix *[8]float32) { + if matrix == nil { + panic("Matrix is nil") + } + C.glUniformMatrix2x4fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) +} + +func (location UniformLocation) UniformMatrix4x2fv(transpose bool, list ...[8]float32) { + if len(list) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniformMatrix4x2fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) +} + +func (location UniformLocation) UniformMatrix4x2f(transpose bool, matrix *[8]float32) { + if matrix == nil { + panic("Matrix is nil") + } + C.glUniformMatrix4x2fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) +} + +func (location UniformLocation) UniformMatrix3x4fv(transpose bool, list ...[12]float32) { + if len(list) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniformMatrix3x4fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) +} + +func (location UniformLocation) UniformMatrix3x4f(transpose bool, matrix *[12]float32) { + if matrix == nil { + panic("Matrix is nil") + } + C.glUniformMatrix3x4fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) +} + +func (location UniformLocation) UniformMatrix4x3fv(transpose bool, list ...[12]float32) { + if len(list) < 1 { + panic("Invalid array length - must be at least 1") + } + C.glUniformMatrix4x3fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) +} + +func (location UniformLocation) UniformMatrix4x3f(transpose bool, matrix *[12]float32) { + if matrix == nil { + panic("Matrix is nil") + } + C.glUniformMatrix4x3fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) +} diff --git a/vendor/github.com/go-gl-legacy/gl/vertex.go b/vendor/github.com/go-gl-legacy/gl/vertex.go new file mode 100644 index 0000000..0422da5 --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/vertex.go @@ -0,0 +1,133 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" + +//void glVertex2d (float64 x, float64 y) +func Vertex2d(x float64, y float64) { + C.glVertex2d(C.GLdouble(x), C.GLdouble(y)) +} + +//void glVertex2dv (const float64 *v) +func Vertex2dv(v *[2]float64) { + C.glVertex2dv((*C.GLdouble)(&v[0])) +} + +//void glVertex2f (float32 x, float32 y) +func Vertex2f(x float32, y float32) { + C.glVertex2f(C.GLfloat(x), C.GLfloat(y)) +} + +//void glVertex2fv (const float *v) +func Vertex2fv(v *[2]float32) { + C.glVertex2fv((*C.GLfloat)(&v[0])) +} + +//void glVertex2i (int x, int y) +func Vertex2i(x int, y int) { + C.glVertex2i(C.GLint(x), C.GLint(y)) +} + +//void glVertex2iv (const int *v) +func Vertex2iv(v *[2]int32) { + C.glVertex2iv((*C.GLint)(&v[0])) +} + +//void glVertex2s (int16 x, int16 y) +func Vertex2s(x int16, y int16) { + C.glVertex2s(C.GLshort(x), C.GLshort(y)) +} + +//void glVertex2sv (const int16 *v) +func Vertex2sv(v *[2]int16) { + C.glVertex2sv((*C.GLshort)(&v[0])) +} + +//void glVertex3d (float64 x, float64 y, float64 z) +func Vertex3d(x float64, y float64, z float64) { + C.glVertex3d(C.GLdouble(x), C.GLdouble(y), C.GLdouble(z)) +} + +//void glVertex3dv (const float64 *v) +func Vertex3dv(v *[3]float64) { + C.glVertex3dv((*C.GLdouble)(&v[0])) +} + +//void glVertex3f (float32 x, float32 y, float32 z) +func Vertex3f(x float32, y float32, z float32) { + C.glVertex3f(C.GLfloat(x), C.GLfloat(y), C.GLfloat(z)) +} + +//void glVertex3fv (const float *v) +func Vertex3fv(v *[3]float32) { + C.glVertex3fv((*C.GLfloat)(&v[0])) +} + +//void glVertex3i (int x, int y, int z) +func Vertex3i(x int, y int, z int) { + C.glVertex3i(C.GLint(x), C.GLint(y), C.GLint(z)) +} + +//void glVertex3iv (const int *v) +func Vertex3iv(v *[3]int32) { + C.glVertex3iv((*C.GLint)(&v[0])) +} + +//void glVertex3s (int16 x, int16 y, int16 z) +func Vertex3s(x int16, y int16, z int16) { + C.glVertex3s(C.GLshort(x), C.GLshort(y), C.GLshort(z)) +} + +//void glVertex3sv (const int16 *v) +func Vertex3sv(v *[3]int16) { + C.glVertex3sv((*C.GLshort)(&v[0])) +} + +//void glVertex4d (float64 x, float64 y, float64 z, float64 w) +func Vertex4d(x float64, y float64, z float64, w float64) { + C.glVertex4d(C.GLdouble(x), C.GLdouble(y), C.GLdouble(z), C.GLdouble(w)) +} + +//void glVertex4dv (const float64 *v) +func Vertex4dv(v *[4]float64) { + C.glVertex4dv((*C.GLdouble)(&v[0])) +} + +//void glVertex4f (float32 x, float32 y, float32 z, float32 w) +func Vertex4f(x float32, y float32, z float32, w float32) { + C.glVertex4f(C.GLfloat(x), C.GLfloat(y), C.GLfloat(z), C.GLfloat(w)) +} + +//void glVertex4fv (const float *v) +func Vertex4fv(v *[4]float32) { + C.glVertex4fv((*C.GLfloat)(&v[0])) +} + +//void glVertex4i (int x, int y, int z, int w) +func Vertex4i(x int, y int, z int, w int) { + C.glVertex4i(C.GLint(x), C.GLint(y), C.GLint(z), C.GLint(w)) +} + +//void glVertex4iv (const int *v) +func Vertex4iv(v *[4]int32) { + C.glVertex4iv((*C.GLint)(&v[0])) +} + +//void glVertex4s (int16 x, int16 y, int16 z, int16 w) +func Vertex4s(x int16, y int16, z int16, w int16) { + C.glVertex4s(C.GLshort(x), C.GLshort(y), C.GLshort(z), C.GLshort(w)) +} + +//void glVertex4sv (const int16 *v) +func Vertex4sv(v *[4]int16) { + C.glVertex4sv((*C.GLshort)(&v[0])) +} + +//void glVertexPointer (int size, GLenum type, int stride, const GLvoid *pointer) +func VertexPointer(size int, typ GLenum, stride int, pointer interface{}) { + C.glVertexPointer(C.GLint(size), C.GLenum(typ), C.GLsizei(stride), ptr(pointer)) +} diff --git a/vendor/github.com/go-gl-legacy/gl/vertexarray.go b/vendor/github.com/go-gl-legacy/gl/vertexarray.go new file mode 100644 index 0000000..45f623f --- /dev/null +++ b/vendor/github.com/go-gl-legacy/gl/vertexarray.go @@ -0,0 +1,41 @@ +// Copyright 2012 The go-gl Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// #include "gl.h" +import "C" + +// Vertex Arrays +type VertexArray Object + +func GenVertexArray() VertexArray { + var a C.GLuint + C.glGenVertexArrays(1, &a) + return VertexArray(a) +} + +func GenVertexArrays(arrays []VertexArray) { + if len(arrays) > 0 { + C.glGenVertexArrays(C.GLsizei(len(arrays)), (*C.GLuint)(&arrays[0])) + } +} + +func (array VertexArray) Delete() { + C.glDeleteVertexArrays(1, (*C.GLuint)(&array)) +} + +func DeleteVertexArrays(arrays []VertexArray) { + if len(arrays) > 0 { + C.glDeleteVertexArrays(C.GLsizei(len(arrays)), (*C.GLuint)(&arrays[0])) + } +} + +func (array VertexArray) Bind() { + C.glBindVertexArray(C.GLuint(array)) +} + +func (array VertexArray) Unbind() { + C.glBindVertexArray(C.GLuint(0)) +} diff --git a/vendor/github.com/robertkrimen/otto/DESIGN.markdown b/vendor/github.com/robertkrimen/otto/DESIGN.markdown new file mode 100644 index 0000000..2887529 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/DESIGN.markdown @@ -0,0 +1 @@ +* Designate the filename of "anonymous" source code by the hash (md5/sha1, etc.) diff --git a/vendor/github.com/robertkrimen/otto/LICENSE b/vendor/github.com/robertkrimen/otto/LICENSE new file mode 100644 index 0000000..b6179fe --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2012 Robert Krimen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/robertkrimen/otto/Makefile b/vendor/github.com/robertkrimen/otto/Makefile new file mode 100644 index 0000000..8d74038 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/Makefile @@ -0,0 +1,63 @@ +.PHONY: test test-race test-release release release-check test-262 +.PHONY: parser +.PHONY: otto assets underscore + +TESTS := \ + ~ + +TEST := -v --run +TEST := -v +TEST := -v --run Test\($(subst $(eval) ,\|,$(TESTS))\) +TEST := . + +test: parser inline.go + go test -i + go test $(TEST) + @echo PASS + +parser: + $(MAKE) -C parser + +inline.go: inline + ./$< > $@ + +################# +# release, test # +################# + +release: test-race test-release + for package in . parser token ast file underscore registry; do (cd $$package && godocdown --signature > README.markdown); done + @echo \*\*\* make release-check + @echo PASS + +release-check: .test + $(MAKE) -C test build test + $(MAKE) -C .test/test262 build test + @echo PASS + +test-262: .test + $(MAKE) -C .test/test262 build test + @echo PASS + +test-release: + go test -i + go test + +test-race: + go test -race -i + go test -race + +################################# +# otto, assets, underscore, ... # +################################# + +otto: + $(MAKE) -C otto + +assets: + mkdir -p .assets + for file in underscore/test/*.js; do tr "\`" "_" < $$file > .assets/`basename $$file`; done + +underscore: + $(MAKE) -C $@ + diff --git a/vendor/github.com/robertkrimen/otto/README.markdown b/vendor/github.com/robertkrimen/otto/README.markdown new file mode 100644 index 0000000..571743b --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/README.markdown @@ -0,0 +1,825 @@ +# otto +-- + import "github.com/robertkrimen/otto" + +Package otto is a JavaScript parser and interpreter written natively in Go. + +http://godoc.org/github.com/robertkrimen/otto + + import ( + "github.com/robertkrimen/otto" + ) + +Run something in the VM + + vm := otto.New() + vm.Run(` + abc = 2 + 2; + console.log("The value of abc is " + abc); // 4 + `) + +Get a value out of the VM + + value, err := vm.Get("abc") + value, _ := value.ToInteger() + } + +Set a number + + vm.Set("def", 11) + vm.Run(` + console.log("The value of def is " + def); + // The value of def is 11 + `) + +Set a string + + vm.Set("xyzzy", "Nothing happens.") + vm.Run(` + console.log(xyzzy.length); // 16 + `) + +Get the value of an expression + + value, _ = vm.Run("xyzzy.length") + { + // value is an int64 with a value of 16 + value, _ := value.ToInteger() + } + +An error happens + + value, err = vm.Run("abcdefghijlmnopqrstuvwxyz.length") + if err != nil { + // err = ReferenceError: abcdefghijlmnopqrstuvwxyz is not defined + // If there is an error, then value.IsUndefined() is true + ... + } + +Set a Go function + + vm.Set("sayHello", func(call otto.FunctionCall) otto.Value { + fmt.Printf("Hello, %s.\n", call.Argument(0).String()) + return otto.Value{} + }) + +Set a Go function that returns something useful + + vm.Set("twoPlus", func(call otto.FunctionCall) otto.Value { + right, _ := call.Argument(0).ToInteger() + result, _ := vm.ToValue(2 + right) + return result + }) + +Use the functions in JavaScript + + result, _ = vm.Run(` + sayHello("Xyzzy"); // Hello, Xyzzy. + sayHello(); // Hello, undefined + + result = twoPlus(2.0); // 4 + `) + + +### Parser + +A separate parser is available in the parser package if you're just interested +in building an AST. + +http://godoc.org/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) + +### otto + +You can run (Go) JavaScript from the commandline with: +http://github.com/robertkrimen/otto/tree/master/otto + + $ go get -v github.com/robertkrimen/otto/otto + +Run JavaScript by entering some source on stdin or by giving otto a filename: + + $ otto example.js + +### underscore + +Optionally include the JavaScript utility-belt library, underscore, with this +import: + + import ( + "github.com/robertkrimen/otto" + _ "github.com/robertkrimen/otto/underscore" + ) + + // Now every otto runtime will come loaded with underscore + +For more information: http://github.com/robertkrimen/otto/tree/master/underscore + + +### Caveat Emptor + +The following are some limitations with otto: + + * "use strict" will parse, but does nothing. + * The regular expression engine (re2/regexp) is not fully compatible with the ECMA5 specification. + + +### Regular Expression Incompatibility + +Go translates JavaScript-style regular expressions into something that is +"regexp" compatible via `parser.TransformRegExp`. Unfortunately, RegExp requires +backtracking for some patterns, and backtracking is not supported by the +standard Go engine: https://code.google.com/p/re2/wiki/Syntax + +Therefore, the following syntax is incompatible: + + (?=) // Lookahead (positive), currently a parsing error + (?!) // Lookahead (backhead), currently a parsing error + \1 // Backreference (\1, \2, \3, ...), currently a parsing error + +A brief discussion of these limitations: "Regexp (?!re)" +https://groups.google.com/forum/?fromgroups=#%21topic/golang-nuts/7qgSDWPIh_E + +More information about re2: https://code.google.com/p/re2/ + +In addition to the above, 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. + + +### Halting Problem + +If you want to stop long running executions (like third-party code), you can use +the interrupt channel to do this: + + package main + + import ( + "errors" + "fmt" + "os" + "time" + + "github.com/robertkrimen/otto" + ) + + var halt = errors.New("Stahp") + + func main() { + runUnsafe(`var abc = [];`) + runUnsafe(` + while (true) { + // Loop forever + }`) + } + + func runUnsafe(unsafe string) { + start := time.Now() + defer func() { + duration := time.Since(start) + if caught := recover(); caught != nil { + if caught == halt { + fmt.Fprintf(os.Stderr, "Some code took to long! Stopping after: %v\n", duration) + return + } + panic(caught) // Something else happened, repanic! + } + fmt.Fprintf(os.Stderr, "Ran code successfully: %v\n", duration) + }() + + vm := otto.New() + 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) + } + +Where is setTimeout/setInterval? + +These timing functions are not actually part of the ECMA-262 specification. +Typically, they belong to the `windows` object (in the browser). It would not be +difficult to provide something like these via Go, but you probably want to wrap +otto in an event loop in that case. + +For an example of how this could be done in Go with otto, see natto: + +http://github.com/robertkrimen/natto + +Here is some more discussion of the issue: + +* http://book.mixu.net/node/ch2.html + +* http://en.wikipedia.org/wiki/Reentrancy_%28computing%29 + +* http://aaroncrane.co.uk/2009/02/perl_safe_signals/ + +## Usage + +```go +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 (:3:9) + at :7:1/ + +#### type FunctionCall + +```go +type FunctionCall struct { + This Value + ArgumentList []Value + Otto *Otto +} +``` + +FunctionCall is an encapsulation of a JavaScript function call. + +#### func (FunctionCall) Argument + +```go +func (self FunctionCall) Argument(index int) Value +``` +Argument will return the value of the argument at the given index. + +If no such argument exists, undefined is returned. + +#### type Object + +```go +type Object struct { +} +``` + +Object is the representation of a JavaScript object. + +#### func (Object) Call + +```go +func (self Object) Call(name string, argumentList ...interface{}) (Value, error) +``` +Call a method on the object. + +It is essentially equivalent to: + + var method, _ := object.Get(name) + method.Call(object, argumentList...) + +An undefined value and an error will result if: + + 1. There is an error during conversion of the argument list + 2. The property is not actually a function + 3. An (uncaught) exception is thrown + +#### func (Object) Class + +```go +func (self Object) Class() string +``` +Class will return the class string of the object. + +The return value will (generally) be one of: + + Object + Function + Array + String + Number + Boolean + Date + RegExp + +#### func (Object) Get + +```go +func (self Object) Get(name string) (Value, error) +``` +Get the value of the property with the given name. + +#### func (Object) Keys + +```go +func (self Object) Keys() []string +``` +Get the keys for the object + +Equivalent to calling Object.keys on the object + +#### func (Object) Set + +```go +func (self Object) Set(name string, value interface{}) error +``` +Set the property of the given name to the given value. + +An error will result if the setting the property triggers an exception (i.e. +read-only), or there is an error during conversion of the given value. + +#### func (Object) Value + +```go +func (self Object) Value() Value +``` +Value will return self as a value. + +#### type Otto + +```go +type Otto struct { + // Interrupt is a channel for interrupting the runtime. You can use this to halt a long running execution, for example. + // See "Halting Problem" for more information. + Interrupt chan func() +} +``` + +Otto is the representation of the JavaScript runtime. Each instance of Otto has +a self-contained namespace. + +#### func New + +```go +func New() *Otto +``` +New will allocate a new JavaScript runtime + +#### func Run + +```go +func Run(src interface{}) (*Otto, Value, error) +``` +Run will allocate a new JavaScript runtime, run the given source on the +allocated runtime, and return the runtime, resulting value, and error (if any). + +src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST +always be in UTF-8. + +src may also be a Script. + +src may also be a Program, but if the AST has been modified, then runtime +behavior is undefined. + +#### func (Otto) Call + +```go +func (self Otto) Call(source string, this interface{}, argumentList ...interface{}) (Value, error) +``` +Call the given JavaScript with a given this and arguments. + +If this is nil, then some special handling takes place to determine the proper +this value, falling back to a "standard" invocation if necessary (where this is +undefined). + +If source begins with "new " (A lowercase new followed by a space), then Call +will invoke the function constructor rather than performing a function call. In +this case, the this argument has no effect. + + // value is a String object + value, _ := vm.Call("Object", nil, "Hello, World.") + + // Likewise... + value, _ := vm.Call("new Object", nil, "Hello, World.") + + // This will perform a concat on the given array and return the result + // value is [ 1, 2, 3, undefined, 4, 5, 6, 7, "abc" ] + value, _ := vm.Call(`[ 1, 2, 3, undefined, 4 ].concat`, nil, 5, 6, 7, "abc") + +#### func (*Otto) Compile + +```go +func (self *Otto) Compile(filename string, src interface{}) (*Script, error) +``` +Compile will parse the given source and return a Script value or nil and an +error if there was a problem during compilation. + + script, err := vm.Compile("", `var abc; if (!abc) abc = 0; abc += 2; abc;`) + vm.Run(script) + +#### func (*Otto) Copy + +```go +func (in *Otto) Copy() *Otto +``` +Copy will create a copy/clone of the runtime. + +Copy is useful for saving some time when creating many similar runtimes. + +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 + +```go +func (self Otto) Get(name string) (Value, error) +``` +Get the value of the top-level binding of the given name. + +If there is an error (like the binding does not exist), then the value will be +undefined. + +#### func (Otto) Object + +```go +func (self Otto) Object(source string) (*Object, error) +``` +Object will run the given source and return the result as an object. + +For example, accessing an existing object: + + object, _ := vm.Object(`Number`) + +Or, creating a new object: + + object, _ := vm.Object(`({ xyzzy: "Nothing happens." })`) + +Or, creating and assigning an object: + + object, _ := vm.Object(`xyzzy = {}`) + object.Set("volume", 11) + +If there is an error (like the source does not result in an object), then nil +and an error is returned. + +#### func (Otto) Run + +```go +func (self Otto) Run(src interface{}) (Value, error) +``` +Run will run the given source (parsing it first if necessary), returning the +resulting value and error (if any) + +src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST +always be in UTF-8. + +If the runtime is unable to parse source, then this function will return +undefined and the parse error (nothing will be evaluated in this case). + +src may also be a Script. + +src may also be a Program, but if the AST has been modified, then runtime +behavior is undefined. + +#### func (Otto) Set + +```go +func (self Otto) Set(name string, value interface{}) error +``` +Set the top-level binding of the given name to the given value. + +Set will automatically apply ToValue to the given value in order to convert it +to a JavaScript value (type Value). + +If there is an error (like the binding is read-only, or the ToValue conversion +fails), then an error is returned. + +If the top-level binding does not exist, it will be created. + +#### func (Otto) ToValue + +```go +func (self Otto) ToValue(value interface{}) (Value, error) +``` +ToValue will convert an interface{} value to a value digestible by +otto/JavaScript. + +#### type Script + +```go +type Script struct { +} +``` + +Script is a handle for some (reusable) JavaScript. Passing a Script value to a +run method will evaluate the JavaScript. + +#### func (*Script) String + +```go +func (self *Script) String() string +``` + +#### type Value + +```go +type Value struct { +} +``` + +Value is the representation of a JavaScript value. + +#### func FalseValue + +```go +func FalseValue() Value +``` +FalseValue will return a value representing false. + +It is equivalent to: + + ToValue(false) + +#### func NaNValue + +```go +func NaNValue() Value +``` +NaNValue will return a value representing NaN. + +It is equivalent to: + + ToValue(math.NaN()) + +#### func NullValue + +```go +func NullValue() Value +``` +NullValue will return a Value representing null. + +#### func ToValue + +```go +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 should use Otto.ToValue instead. + +#### func TrueValue + +```go +func TrueValue() Value +``` +TrueValue will return a value representing true. + +It is equivalent to: + + ToValue(true) + +#### func UndefinedValue + +```go +func UndefinedValue() Value +``` +UndefinedValue will return a Value representing undefined. + +#### func (Value) Call + +```go +func (value Value) Call(this Value, argumentList ...interface{}) (Value, error) +``` +Call the value as a function with the given this value and argument list and +return the result of invocation. It is essentially equivalent to: + + value.apply(thisValue, argumentList) + +An undefined value and an error will result if: + + 1. There is an error during conversion of the argument list + 2. The value is not actually a function + 3. An (uncaught) exception is thrown + +#### func (Value) Class + +```go +func (value Value) Class() string +``` +Class will return the class string of the value or the empty string if value is +not an object. + +The return value will (generally) be one of: + + Object + Function + Array + String + Number + Boolean + Date + RegExp + +#### func (Value) Export + +```go +func (self Value) Export() (interface{}, error) +``` +Export will attempt to convert the value to a Go representation and return it +via an interface{} kind. + +Export returns an error, but it will always be nil. It is present for backwards +compatibility. + +If a reasonable conversion is not possible, then the original value is returned. + + undefined -> nil (FIXME?: Should be Value{}) + null -> nil + boolean -> bool + number -> A number type (int, float32, uint64, ...) + string -> string + Array -> []interface{} + Object -> map[string]interface{} + +#### func (Value) IsBoolean + +```go +func (value Value) IsBoolean() bool +``` +IsBoolean will return true if value is a boolean (primitive). + +#### func (Value) IsDefined + +```go +func (value Value) IsDefined() bool +``` +IsDefined will return false if the value is undefined, and true otherwise. + +#### func (Value) IsFunction + +```go +func (value Value) IsFunction() bool +``` +IsFunction will return true if value is a function. + +#### func (Value) IsNaN + +```go +func (value Value) IsNaN() bool +``` +IsNaN will return true if value is NaN (or would convert to NaN). + +#### func (Value) IsNull + +```go +func (value Value) IsNull() bool +``` +IsNull will return true if the value is null, and false otherwise. + +#### func (Value) IsNumber + +```go +func (value Value) IsNumber() bool +``` +IsNumber will return true if value is a number (primitive). + +#### func (Value) IsObject + +```go +func (value Value) IsObject() bool +``` +IsObject will return true if value is an object. + +#### func (Value) IsPrimitive + +```go +func (value Value) IsPrimitive() bool +``` +IsPrimitive will return true if value is a primitive (any kind of primitive). + +#### func (Value) IsString + +```go +func (value Value) IsString() bool +``` +IsString will return true if value is a string (primitive). + +#### func (Value) IsUndefined + +```go +func (value Value) IsUndefined() bool +``` +IsUndefined will return true if the value is undefined, and false otherwise. + +#### func (Value) Object + +```go +func (value Value) Object() *Object +``` +Object will return the object of the value, or nil if value is not an object. + +This method will not do any implicit conversion. For example, calling this +method on a string primitive value will not return a String object. + +#### func (Value) String + +```go +func (value Value) String() string +``` +String will return the value as a string. + +This method will make return the empty string if there is an error. + +#### func (Value) ToBoolean + +```go +func (value Value) ToBoolean() (bool, error) +``` +ToBoolean will convert the value to a boolean (bool). + + ToValue(0).ToBoolean() => false + ToValue("").ToBoolean() => false + ToValue(true).ToBoolean() => true + ToValue(1).ToBoolean() => true + ToValue("Nothing happens").ToBoolean() => true + +If there is an error during the conversion process (like an uncaught exception), +then the result will be false and an error. + +#### func (Value) ToFloat + +```go +func (value Value) ToFloat() (float64, error) +``` +ToFloat will convert the value to a number (float64). + + ToValue(0).ToFloat() => 0. + ToValue(1.1).ToFloat() => 1.1 + ToValue("11").ToFloat() => 11. + +If there is an error during the conversion process (like an uncaught exception), +then the result will be 0 and an error. + +#### func (Value) ToInteger + +```go +func (value Value) ToInteger() (int64, error) +``` +ToInteger will convert the value to a number (int64). + + ToValue(0).ToInteger() => 0 + ToValue(1.1).ToInteger() => 1 + ToValue("11").ToInteger() => 11 + +If there is an error during the conversion process (like an uncaught exception), +then the result will be 0 and an error. + +#### func (Value) ToString + +```go +func (value Value) ToString() (string, error) +``` +ToString will convert the value to a string (string). + + ToValue(0).ToString() => "0" + ToValue(false).ToString() => "false" + ToValue(1.1).ToString() => "1.1" + ToValue("11").ToString() => "11" + ToValue('Nothing happens.').ToString() => "Nothing happens." + +If there is an error during the conversion process (like an uncaught exception), +then the result will be the empty string ("") and an error. + +-- +**godocdown** http://github.com/robertkrimen/godocdown diff --git a/vendor/github.com/robertkrimen/otto/ast/README.markdown b/vendor/github.com/robertkrimen/otto/ast/README.markdown new file mode 100644 index 0000000..a785da9 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/ast/README.markdown @@ -0,0 +1,1068 @@ +# ast +-- + import "github.com/robertkrimen/otto/ast" + +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. + +## Usage + +#### type ArrayLiteral + +```go +type ArrayLiteral struct { + LeftBracket file.Idx + RightBracket file.Idx + Value []Expression +} +``` + + +#### func (*ArrayLiteral) Idx0 + +```go +func (self *ArrayLiteral) Idx0() file.Idx +``` + +#### func (*ArrayLiteral) Idx1 + +```go +func (self *ArrayLiteral) Idx1() file.Idx +``` + +#### type AssignExpression + +```go +type AssignExpression struct { + Operator token.Token + Left Expression + Right Expression +} +``` + + +#### func (*AssignExpression) Idx0 + +```go +func (self *AssignExpression) Idx0() file.Idx +``` + +#### func (*AssignExpression) Idx1 + +```go +func (self *AssignExpression) Idx1() file.Idx +``` + +#### type BadExpression + +```go +type BadExpression struct { + From file.Idx + To file.Idx +} +``` + + +#### func (*BadExpression) Idx0 + +```go +func (self *BadExpression) Idx0() file.Idx +``` + +#### func (*BadExpression) Idx1 + +```go +func (self *BadExpression) Idx1() file.Idx +``` + +#### type BadStatement + +```go +type BadStatement struct { + From file.Idx + To file.Idx +} +``` + + +#### func (*BadStatement) Idx0 + +```go +func (self *BadStatement) Idx0() file.Idx +``` + +#### func (*BadStatement) Idx1 + +```go +func (self *BadStatement) Idx1() file.Idx +``` + +#### type BinaryExpression + +```go +type BinaryExpression struct { + Operator token.Token + Left Expression + Right Expression + Comparison bool +} +``` + + +#### func (*BinaryExpression) Idx0 + +```go +func (self *BinaryExpression) Idx0() file.Idx +``` + +#### func (*BinaryExpression) Idx1 + +```go +func (self *BinaryExpression) Idx1() file.Idx +``` + +#### type BlockStatement + +```go +type BlockStatement struct { + LeftBrace file.Idx + List []Statement + RightBrace file.Idx +} +``` + + +#### func (*BlockStatement) Idx0 + +```go +func (self *BlockStatement) Idx0() file.Idx +``` + +#### func (*BlockStatement) Idx1 + +```go +func (self *BlockStatement) Idx1() file.Idx +``` + +#### type BooleanLiteral + +```go +type BooleanLiteral struct { + Idx file.Idx + Literal string + Value bool +} +``` + + +#### func (*BooleanLiteral) Idx0 + +```go +func (self *BooleanLiteral) Idx0() file.Idx +``` + +#### func (*BooleanLiteral) Idx1 + +```go +func (self *BooleanLiteral) Idx1() file.Idx +``` + +#### type BracketExpression + +```go +type BracketExpression struct { + Left Expression + Member Expression + LeftBracket file.Idx + RightBracket file.Idx +} +``` + + +#### func (*BracketExpression) Idx0 + +```go +func (self *BracketExpression) Idx0() file.Idx +``` + +#### func (*BracketExpression) Idx1 + +```go +func (self *BracketExpression) Idx1() file.Idx +``` + +#### type BranchStatement + +```go +type BranchStatement struct { + Idx file.Idx + Token token.Token + Label *Identifier +} +``` + + +#### func (*BranchStatement) Idx0 + +```go +func (self *BranchStatement) Idx0() file.Idx +``` + +#### func (*BranchStatement) Idx1 + +```go +func (self *BranchStatement) Idx1() file.Idx +``` + +#### type CallExpression + +```go +type CallExpression struct { + Callee Expression + LeftParenthesis file.Idx + ArgumentList []Expression + RightParenthesis file.Idx +} +``` + + +#### func (*CallExpression) Idx0 + +```go +func (self *CallExpression) Idx0() file.Idx +``` + +#### func (*CallExpression) Idx1 + +```go +func (self *CallExpression) Idx1() file.Idx +``` + +#### type CaseStatement + +```go +type CaseStatement struct { + Case file.Idx + Test Expression + Consequent []Statement +} +``` + + +#### func (*CaseStatement) Idx0 + +```go +func (self *CaseStatement) Idx0() file.Idx +``` + +#### func (*CaseStatement) Idx1 + +```go +func (self *CaseStatement) Idx1() file.Idx +``` + +#### type CatchStatement + +```go +type CatchStatement struct { + Catch file.Idx + Parameter *Identifier + Body Statement +} +``` + + +#### func (*CatchStatement) Idx0 + +```go +func (self *CatchStatement) Idx0() file.Idx +``` + +#### func (*CatchStatement) Idx1 + +```go +func (self *CatchStatement) Idx1() file.Idx +``` + +#### type ConditionalExpression + +```go +type ConditionalExpression struct { + Test Expression + Consequent Expression + Alternate Expression +} +``` + + +#### func (*ConditionalExpression) Idx0 + +```go +func (self *ConditionalExpression) Idx0() file.Idx +``` + +#### func (*ConditionalExpression) Idx1 + +```go +func (self *ConditionalExpression) Idx1() file.Idx +``` + +#### type DebuggerStatement + +```go +type DebuggerStatement struct { + Debugger file.Idx +} +``` + + +#### func (*DebuggerStatement) Idx0 + +```go +func (self *DebuggerStatement) Idx0() file.Idx +``` + +#### func (*DebuggerStatement) Idx1 + +```go +func (self *DebuggerStatement) Idx1() file.Idx +``` + +#### type Declaration + +```go +type Declaration interface { + // contains filtered or unexported methods +} +``` + +All declaration nodes implement the Declaration interface. + +#### type DoWhileStatement + +```go +type DoWhileStatement struct { + Do file.Idx + Test Expression + Body Statement +} +``` + + +#### func (*DoWhileStatement) Idx0 + +```go +func (self *DoWhileStatement) Idx0() file.Idx +``` + +#### func (*DoWhileStatement) Idx1 + +```go +func (self *DoWhileStatement) Idx1() file.Idx +``` + +#### type DotExpression + +```go +type DotExpression struct { + Left Expression + Identifier Identifier +} +``` + + +#### func (*DotExpression) Idx0 + +```go +func (self *DotExpression) Idx0() file.Idx +``` + +#### func (*DotExpression) Idx1 + +```go +func (self *DotExpression) Idx1() file.Idx +``` + +#### type EmptyStatement + +```go +type EmptyStatement struct { + Semicolon file.Idx +} +``` + + +#### func (*EmptyStatement) Idx0 + +```go +func (self *EmptyStatement) Idx0() file.Idx +``` + +#### func (*EmptyStatement) Idx1 + +```go +func (self *EmptyStatement) Idx1() file.Idx +``` + +#### type Expression + +```go +type Expression interface { + Node + // contains filtered or unexported methods +} +``` + +All expression nodes implement the Expression interface. + +#### type ExpressionStatement + +```go +type ExpressionStatement struct { + Expression Expression +} +``` + + +#### func (*ExpressionStatement) Idx0 + +```go +func (self *ExpressionStatement) Idx0() file.Idx +``` + +#### func (*ExpressionStatement) Idx1 + +```go +func (self *ExpressionStatement) Idx1() file.Idx +``` + +#### type ForInStatement + +```go +type ForInStatement struct { + For file.Idx + Into Expression + Source Expression + Body Statement +} +``` + + +#### func (*ForInStatement) Idx0 + +```go +func (self *ForInStatement) Idx0() file.Idx +``` + +#### func (*ForInStatement) Idx1 + +```go +func (self *ForInStatement) Idx1() file.Idx +``` + +#### type ForStatement + +```go +type ForStatement struct { + For file.Idx + Initializer Expression + Update Expression + Test Expression + Body Statement +} +``` + + +#### func (*ForStatement) Idx0 + +```go +func (self *ForStatement) Idx0() file.Idx +``` + +#### func (*ForStatement) Idx1 + +```go +func (self *ForStatement) Idx1() file.Idx +``` + +#### type FunctionDeclaration + +```go +type FunctionDeclaration struct { + Function *FunctionLiteral +} +``` + + +#### type FunctionLiteral + +```go +type FunctionLiteral struct { + Function file.Idx + Name *Identifier + ParameterList *ParameterList + Body Statement + Source string + + DeclarationList []Declaration +} +``` + + +#### func (*FunctionLiteral) Idx0 + +```go +func (self *FunctionLiteral) Idx0() file.Idx +``` + +#### func (*FunctionLiteral) Idx1 + +```go +func (self *FunctionLiteral) Idx1() file.Idx +``` + +#### type Identifier + +```go +type Identifier struct { + Name string + Idx file.Idx +} +``` + + +#### func (*Identifier) Idx0 + +```go +func (self *Identifier) Idx0() file.Idx +``` + +#### func (*Identifier) Idx1 + +```go +func (self *Identifier) Idx1() file.Idx +``` + +#### type IfStatement + +```go +type IfStatement struct { + If file.Idx + Test Expression + Consequent Statement + Alternate Statement +} +``` + + +#### func (*IfStatement) Idx0 + +```go +func (self *IfStatement) Idx0() file.Idx +``` + +#### func (*IfStatement) Idx1 + +```go +func (self *IfStatement) Idx1() file.Idx +``` + +#### type LabelledStatement + +```go +type LabelledStatement struct { + Label *Identifier + Colon file.Idx + Statement Statement +} +``` + + +#### func (*LabelledStatement) Idx0 + +```go +func (self *LabelledStatement) Idx0() file.Idx +``` + +#### func (*LabelledStatement) Idx1 + +```go +func (self *LabelledStatement) Idx1() file.Idx +``` + +#### type NewExpression + +```go +type NewExpression struct { + New file.Idx + Callee Expression + LeftParenthesis file.Idx + ArgumentList []Expression + RightParenthesis file.Idx +} +``` + + +#### func (*NewExpression) Idx0 + +```go +func (self *NewExpression) Idx0() file.Idx +``` + +#### func (*NewExpression) Idx1 + +```go +func (self *NewExpression) Idx1() file.Idx +``` + +#### type Node + +```go +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 +} +``` + +All nodes implement the Node interface. + +#### type NullLiteral + +```go +type NullLiteral struct { + Idx file.Idx + Literal string +} +``` + + +#### func (*NullLiteral) Idx0 + +```go +func (self *NullLiteral) Idx0() file.Idx +``` + +#### func (*NullLiteral) Idx1 + +```go +func (self *NullLiteral) Idx1() file.Idx +``` + +#### type NumberLiteral + +```go +type NumberLiteral struct { + Idx file.Idx + Literal string + Value interface{} +} +``` + + +#### func (*NumberLiteral) Idx0 + +```go +func (self *NumberLiteral) Idx0() file.Idx +``` + +#### func (*NumberLiteral) Idx1 + +```go +func (self *NumberLiteral) Idx1() file.Idx +``` + +#### type ObjectLiteral + +```go +type ObjectLiteral struct { + LeftBrace file.Idx + RightBrace file.Idx + Value []Property +} +``` + + +#### func (*ObjectLiteral) Idx0 + +```go +func (self *ObjectLiteral) Idx0() file.Idx +``` + +#### func (*ObjectLiteral) Idx1 + +```go +func (self *ObjectLiteral) Idx1() file.Idx +``` + +#### type ParameterList + +```go +type ParameterList struct { + Opening file.Idx + List []*Identifier + Closing file.Idx +} +``` + + +#### type Program + +```go +type Program struct { + Body []Statement + + DeclarationList []Declaration + + File *file.File +} +``` + + +#### func (*Program) Idx0 + +```go +func (self *Program) Idx0() file.Idx +``` + +#### func (*Program) Idx1 + +```go +func (self *Program) Idx1() file.Idx +``` + +#### type Property + +```go +type Property struct { + Key string + Kind string + Value Expression +} +``` + + +#### type RegExpLiteral + +```go +type RegExpLiteral struct { + Idx file.Idx + Literal string + Pattern string + Flags string + Value string +} +``` + + +#### func (*RegExpLiteral) Idx0 + +```go +func (self *RegExpLiteral) Idx0() file.Idx +``` + +#### func (*RegExpLiteral) Idx1 + +```go +func (self *RegExpLiteral) Idx1() file.Idx +``` + +#### type ReturnStatement + +```go +type ReturnStatement struct { + Return file.Idx + Argument Expression +} +``` + + +#### func (*ReturnStatement) Idx0 + +```go +func (self *ReturnStatement) Idx0() file.Idx +``` + +#### func (*ReturnStatement) Idx1 + +```go +func (self *ReturnStatement) Idx1() file.Idx +``` + +#### type SequenceExpression + +```go +type SequenceExpression struct { + Sequence []Expression +} +``` + + +#### func (*SequenceExpression) Idx0 + +```go +func (self *SequenceExpression) Idx0() file.Idx +``` + +#### func (*SequenceExpression) Idx1 + +```go +func (self *SequenceExpression) Idx1() file.Idx +``` + +#### type Statement + +```go +type Statement interface { + Node + // contains filtered or unexported methods +} +``` + +All statement nodes implement the Statement interface. + +#### type StringLiteral + +```go +type StringLiteral struct { + Idx file.Idx + Literal string + Value string +} +``` + + +#### func (*StringLiteral) Idx0 + +```go +func (self *StringLiteral) Idx0() file.Idx +``` + +#### func (*StringLiteral) Idx1 + +```go +func (self *StringLiteral) Idx1() file.Idx +``` + +#### type SwitchStatement + +```go +type SwitchStatement struct { + Switch file.Idx + Discriminant Expression + Default int + Body []*CaseStatement +} +``` + + +#### func (*SwitchStatement) Idx0 + +```go +func (self *SwitchStatement) Idx0() file.Idx +``` + +#### func (*SwitchStatement) Idx1 + +```go +func (self *SwitchStatement) Idx1() file.Idx +``` + +#### type ThisExpression + +```go +type ThisExpression struct { + Idx file.Idx +} +``` + + +#### func (*ThisExpression) Idx0 + +```go +func (self *ThisExpression) Idx0() file.Idx +``` + +#### func (*ThisExpression) Idx1 + +```go +func (self *ThisExpression) Idx1() file.Idx +``` + +#### type ThrowStatement + +```go +type ThrowStatement struct { + Throw file.Idx + Argument Expression +} +``` + + +#### func (*ThrowStatement) Idx0 + +```go +func (self *ThrowStatement) Idx0() file.Idx +``` + +#### func (*ThrowStatement) Idx1 + +```go +func (self *ThrowStatement) Idx1() file.Idx +``` + +#### type TryStatement + +```go +type TryStatement struct { + Try file.Idx + Body Statement + Catch *CatchStatement + Finally Statement +} +``` + + +#### func (*TryStatement) Idx0 + +```go +func (self *TryStatement) Idx0() file.Idx +``` + +#### func (*TryStatement) Idx1 + +```go +func (self *TryStatement) Idx1() file.Idx +``` + +#### type UnaryExpression + +```go +type UnaryExpression struct { + Operator token.Token + Idx file.Idx // If a prefix operation + Operand Expression + Postfix bool +} +``` + + +#### func (*UnaryExpression) Idx0 + +```go +func (self *UnaryExpression) Idx0() file.Idx +``` + +#### func (*UnaryExpression) Idx1 + +```go +func (self *UnaryExpression) Idx1() file.Idx +``` + +#### type VariableDeclaration + +```go +type VariableDeclaration struct { + Var file.Idx + List []*VariableExpression +} +``` + + +#### type VariableExpression + +```go +type VariableExpression struct { + Name string + Idx file.Idx + Initializer Expression +} +``` + + +#### func (*VariableExpression) Idx0 + +```go +func (self *VariableExpression) Idx0() file.Idx +``` + +#### func (*VariableExpression) Idx1 + +```go +func (self *VariableExpression) Idx1() file.Idx +``` + +#### type VariableStatement + +```go +type VariableStatement struct { + Var file.Idx + List []Expression +} +``` + + +#### func (*VariableStatement) Idx0 + +```go +func (self *VariableStatement) Idx0() file.Idx +``` + +#### func (*VariableStatement) Idx1 + +```go +func (self *VariableStatement) Idx1() file.Idx +``` + +#### type WhileStatement + +```go +type WhileStatement struct { + While file.Idx + Test Expression + Body Statement +} +``` + + +#### func (*WhileStatement) Idx0 + +```go +func (self *WhileStatement) Idx0() file.Idx +``` + +#### func (*WhileStatement) Idx1 + +```go +func (self *WhileStatement) Idx1() file.Idx +``` + +#### type WithStatement + +```go +type WithStatement struct { + With file.Idx + Object Expression + Body Statement +} +``` + + +#### func (*WithStatement) Idx0 + +```go +func (self *WithStatement) Idx0() file.Idx +``` + +#### func (*WithStatement) Idx1 + +```go +func (self *WithStatement) Idx1() file.Idx +``` + +-- +**godocdown** http://github.com/robertkrimen/godocdown diff --git a/vendor/github.com/robertkrimen/otto/ast/node.go b/vendor/github.com/robertkrimen/otto/ast/node.go new file mode 100644 index 0000000..eb46f86 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/ast/node.go @@ -0,0 +1,498 @@ +/* +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 + + File *file.File +} + +// ==== // +// 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() } diff --git a/vendor/github.com/robertkrimen/otto/builtin.go b/vendor/github.com/robertkrimen/otto/builtin.go new file mode 100644 index 0000000..c3375a1 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin.go @@ -0,0 +1,353 @@ +package otto + +import ( + "encoding/hex" + "math" + "net/url" + "regexp" + "strconv" + "strings" + "unicode/utf16" + "unicode/utf8" +) + +// Global +func builtinGlobal_eval(call FunctionCall) Value { + src := call.Argument(0) + if !src.IsString() { + return src + } + runtime := call.runtime + 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, true) + if returnValue.isEmpty() { + return Value{} + } + return returnValue +} + +func builtinGlobal_isNaN(call FunctionCall) Value { + value := call.Argument(0).float64() + return toValue_bool(math.IsNaN(value)) +} + +func builtinGlobal_isFinite(call FunctionCall) Value { + value := call.Argument(0).float64() + return toValue_bool(!math.IsNaN(value) && !math.IsInf(value, 0)) +} + +// radix 3 => 2 (ASCII 50) +47 +// radix 11 => A/a (ASCII 65/97) +54/+86 +var parseInt_alphabetTable = func() []string { + table := []string{"", "", "01"} + for radix := 3; radix <= 36; radix += 1 { + alphabet := table[radix-1] + if radix <= 10 { + alphabet += string(radix + 47) + } else { + alphabet += string(radix+54) + string(radix+86) + } + table = append(table, alphabet) + } + return table +}() + +func digitValue(chr rune) int { + switch { + case '0' <= chr && chr <= '9': + return int(chr - '0') + case 'a' <= chr && chr <= 'z': + return int(chr - 'a' + 10) + case 'A' <= chr && chr <= 'Z': + return int(chr - 'A' + 10) + } + return 36 // Larger than any legal digit value +} + +func builtinGlobal_parseInt(call FunctionCall) Value { + input := strings.TrimSpace(call.Argument(0).string()) + if len(input) == 0 { + return NaNValue() + } + + radix := int(toInt32(call.Argument(1))) + + negative := false + switch input[0] { + case '+': + input = input[1:] + case '-': + negative = true + input = input[1:] + } + + strip := true + if radix == 0 { + radix = 10 + } else { + if radix < 2 || radix > 36 { + return NaNValue() + } else if radix != 16 { + strip = false + } + } + + switch len(input) { + case 0: + return NaNValue() + case 1: + default: + if strip { + if input[0] == '0' && (input[1] == 'x' || input[1] == 'X') { + input = input[2:] + radix = 16 + } + } + } + + base := radix + index := 0 + for ; index < len(input); index++ { + digit := digitValue(rune(input[index])) // If not ASCII, then an error anyway + if digit >= base { + break + } + } + input = input[0:index] + + value, err := strconv.ParseInt(input, radix, 64) + if err != nil { + if err.(*strconv.NumError).Err == strconv.ErrRange { + base := float64(base) + // Could just be a very large number (e.g. 0x8000000000000000) + var value float64 + for _, chr := range input { + digit := float64(digitValue(chr)) + if digit >= base { + goto error + } + value = value*base + digit + } + if negative { + value *= -1 + } + return toValue_float64(value) + } + error: + return NaNValue() + } + if negative { + value *= -1 + } + + return toValue_int64(value) +} + +var parseFloat_matchBadSpecial = regexp.MustCompile(`[\+\-]?(?:[Ii]nf$|infinity)`) +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(call.Argument(0).string()) + if parseFloat_matchBadSpecial.MatchString(input) { + return NaNValue() + } + value, err := strconv.ParseFloat(input, 64) + if err != nil { + for end := len(input); end > 0; end -= 1 { + input := input[0:end] + if !parseFloat_matchValid.MatchString(input) { + return NaNValue() + } + value, err = strconv.ParseFloat(input, 64) + if err == nil { + break + } + } + if err != nil { + return NaNValue() + } + } + return toValue_float64(value) +} + +// encodeURI/decodeURI + +func _builtinGlobal_encodeURI(call FunctionCall, escape *regexp.Regexp) Value { + value := call.Argument(0) + var input []uint16 + switch vl := value.value.(type) { + case []uint16: + input = vl + default: + input = utf16.Encode([]rune(value.string())) + } + if len(input) == 0 { + return toValue_string("") + } + output := []byte{} + length := len(input) + encode := make([]byte, 4) + for index := 0; index < length; { + value := input[index] + decode := utf16.Decode(input[index : index+1]) + if value >= 0xDC00 && value <= 0xDFFF { + panic(call.runtime.panicURIError("URI malformed")) + } + if value >= 0xD800 && value <= 0xDBFF { + index += 1 + if index >= length { + panic(call.runtime.panicURIError("URI malformed")) + } + // input = ..., value, value1, ... + value1 := input[index] + if value1 < 0xDC00 || value1 > 0xDFFF { + panic(call.runtime.panicURIError("URI malformed")) + } + decode = []rune{((rune(value) - 0xD800) * 0x400) + (rune(value1) - 0xDC00) + 0x10000} + } + index += 1 + size := utf8.EncodeRune(encode, decode[0]) + encode := encode[0:size] + output = append(output, encode...) + } + { + value := escape.ReplaceAllFunc(output, func(target []byte) []byte { + // Probably a better way of doing this + if target[0] == ' ' { + return []byte("%20") + } + return []byte(url.QueryEscape(string(target))) + }) + return toValue_string(string(value)) + } +} + +var encodeURI_Regexp = regexp.MustCompile(`([^~!@#$&*()=:/,;?+'])`) + +func builtinGlobal_encodeURI(call FunctionCall) Value { + return _builtinGlobal_encodeURI(call, encodeURI_Regexp) +} + +var encodeURIComponent_Regexp = regexp.MustCompile(`([^~!*()'])`) + +func builtinGlobal_encodeURIComponent(call FunctionCall) Value { + return _builtinGlobal_encodeURI(call, encodeURIComponent_Regexp) +} + +// 3B/2F/3F/3A/40/26/3D/2B/24/2C/23 +var decodeURI_guard = regexp.MustCompile(`(?i)(?:%)(3B|2F|3F|3A|40|26|3D|2B|24|2C|23)`) + +func _decodeURI(input string, reserve bool) (string, bool) { + if reserve { + input = decodeURI_guard.ReplaceAllString(input, "%25$1") + } + input = strings.Replace(input, "+", "%2B", -1) // Ugly hack to make QueryUnescape work with our use case + output, err := url.QueryUnescape(input) + if err != nil || !utf8.ValidString(output) { + return "", true + } + return output, false +} + +func builtinGlobal_decodeURI(call FunctionCall) Value { + output, err := _decodeURI(call.Argument(0).string(), true) + if err { + panic(call.runtime.panicURIError("URI malformed")) + } + return toValue_string(output) +} + +func builtinGlobal_decodeURIComponent(call FunctionCall) Value { + output, err := _decodeURI(call.Argument(0).string(), false) + if err { + panic(call.runtime.panicURIError("URI malformed")) + } + return toValue_string(output) +} + +// escape/unescape + +func builtin_shouldEscape(chr byte) bool { + if 'A' <= chr && chr <= 'Z' || 'a' <= chr && chr <= 'z' || '0' <= chr && chr <= '9' { + return false + } + return !strings.ContainsRune("*_+-./", rune(chr)) +} + +const escapeBase16 = "0123456789ABCDEF" + +func builtin_escape(input string) string { + output := make([]byte, 0, len(input)) + length := len(input) + for index := 0; index < length; { + if builtin_shouldEscape(input[index]) { + chr, width := utf8.DecodeRuneInString(input[index:]) + chr16 := utf16.Encode([]rune{chr})[0] + if 256 > chr16 { + output = append(output, '%', + escapeBase16[chr16>>4], + escapeBase16[chr16&15], + ) + } else { + output = append(output, '%', 'u', + escapeBase16[chr16>>12], + escapeBase16[(chr16>>8)&15], + escapeBase16[(chr16>>4)&15], + escapeBase16[chr16&15], + ) + } + index += width + + } else { + output = append(output, input[index]) + index += 1 + } + } + return string(output) +} + +func builtin_unescape(input string) string { + output := make([]rune, 0, len(input)) + length := len(input) + for index := 0; index < length; { + if input[index] == '%' { + if index <= length-6 && input[index+1] == 'u' { + byte16, err := hex.DecodeString(input[index+2 : index+6]) + if err == nil { + value := uint16(byte16[0])<<8 + uint16(byte16[1]) + chr := utf16.Decode([]uint16{value})[0] + output = append(output, chr) + index += 6 + continue + } + } + if index <= length-3 { + byte8, err := hex.DecodeString(input[index+1 : index+3]) + if err == nil { + value := uint16(byte8[0]) + chr := utf16.Decode([]uint16{value})[0] + output = append(output, chr) + index += 3 + continue + } + } + } + output = append(output, rune(input[index])) + index += 1 + } + return string(output) +} + +func builtinGlobal_escape(call FunctionCall) Value { + return toValue_string(builtin_escape(call.Argument(0).string())) +} + +func builtinGlobal_unescape(call FunctionCall) Value { + return toValue_string(builtin_unescape(call.Argument(0).string())) +} diff --git a/vendor/github.com/robertkrimen/otto/builtin_array.go b/vendor/github.com/robertkrimen/otto/builtin_array.go new file mode 100644 index 0000000..44bf885 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_array.go @@ -0,0 +1,672 @@ +package otto + +import ( + "strconv" + "strings" +) + +// Array + +func builtinArray(call FunctionCall) Value { + return toValue_object(builtinNewArrayNative(call.runtime, call.ArgumentList)) +} + +func builtinNewArray(self *_object, argumentList []Value) Value { + return toValue_object(builtinNewArrayNative(self.runtime, argumentList)) +} + +func builtinNewArrayNative(runtime *_runtime, argumentList []Value) *_object { + if len(argumentList) == 1 { + firstArgument := argumentList[0] + if firstArgument.IsNumber() { + return runtime.newArray(arrayUint32(runtime, firstArgument)) + } + } + return runtime.newArrayOf(argumentList) +} + +func builtinArray_toString(call FunctionCall) Value { + thisObject := call.thisObject() + join := thisObject.get("join") + if join.isCallable() { + join := join._object() + return join.call(call.This, call.ArgumentList, false, nativeFrame) + } + return builtinObject_toString(call) +} + +func builtinArray_toLocaleString(call FunctionCall) Value { + separator := "," + thisObject := call.thisObject() + length := int64(toUint32(thisObject.get("length"))) + if length == 0 { + return toValue_string("") + } + stringList := make([]string, 0, length) + for index := int64(0); index < length; index += 1 { + value := thisObject.get(arrayIndexToString(index)) + stringValue := "" + switch value.kind { + case valueEmpty, valueUndefined, valueNull: + default: + object := call.runtime.toObject(value) + toLocaleString := object.get("toLocaleString") + if !toLocaleString.isCallable() { + panic(call.runtime.panicTypeError()) + } + stringValue = toLocaleString.call(call.runtime, toValue_object(object)).string() + } + stringList = append(stringList, stringValue) + } + return toValue_string(strings.Join(stringList, separator)) +} + +func builtinArray_concat(call FunctionCall) Value { + thisObject := call.thisObject() + valueArray := []Value{} + source := append([]Value{toValue_object(thisObject)}, call.ArgumentList...) + for _, item := range source { + switch item.kind { + case valueObject: + object := item._object() + if isArray(object) { + length := object.get("length").number().int64 + for index := int64(0); index < length; index += 1 { + name := strconv.FormatInt(index, 10) + if object.hasProperty(name) { + valueArray = append(valueArray, object.get(name)) + } else { + valueArray = append(valueArray, Value{}) + } + } + continue + } + fallthrough + default: + valueArray = append(valueArray, item) + } + } + return toValue_object(call.runtime.newArrayOf(valueArray)) +} + +func builtinArray_shift(call FunctionCall) Value { + thisObject := call.thisObject() + length := int64(toUint32(thisObject.get("length"))) + if 0 == length { + thisObject.put("length", toValue_int64(0), true) + return Value{} + } + first := thisObject.get("0") + for index := int64(1); index < length; index++ { + from := arrayIndexToString(index) + to := arrayIndexToString(index - 1) + if thisObject.hasProperty(from) { + thisObject.put(to, thisObject.get(from), true) + } else { + thisObject.delete(to, true) + } + } + thisObject.delete(arrayIndexToString(length-1), true) + thisObject.put("length", toValue_int64(length-1), true) + return first +} + +func builtinArray_push(call FunctionCall) Value { + thisObject := call.thisObject() + itemList := call.ArgumentList + index := int64(toUint32(thisObject.get("length"))) + for len(itemList) > 0 { + thisObject.put(arrayIndexToString(index), itemList[0], true) + itemList = itemList[1:] + index += 1 + } + length := toValue_int64(index) + thisObject.put("length", length, true) + return length +} + +func builtinArray_pop(call FunctionCall) Value { + thisObject := call.thisObject() + length := int64(toUint32(thisObject.get("length"))) + if 0 == length { + thisObject.put("length", toValue_uint32(0), true) + return Value{} + } + last := thisObject.get(arrayIndexToString(length - 1)) + thisObject.delete(arrayIndexToString(length-1), true) + thisObject.put("length", toValue_int64(length-1), true) + return last +} + +func builtinArray_join(call FunctionCall) Value { + separator := "," + { + argument := call.Argument(0) + if argument.IsDefined() { + separator = argument.string() + } + } + thisObject := call.thisObject() + length := int64(toUint32(thisObject.get("length"))) + if length == 0 { + return toValue_string("") + } + stringList := make([]string, 0, length) + for index := int64(0); index < length; index += 1 { + value := thisObject.get(arrayIndexToString(index)) + stringValue := "" + switch value.kind { + case valueEmpty, valueUndefined, valueNull: + default: + stringValue = value.string() + } + stringList = append(stringList, stringValue) + } + return toValue_string(strings.Join(stringList, separator)) +} + +func builtinArray_splice(call FunctionCall) Value { + thisObject := call.thisObject() + length := int64(toUint32(thisObject.get("length"))) + + start := valueToRangeIndex(call.Argument(0), length, false) + deleteCount := valueToRangeIndex(call.Argument(1), int64(length)-start, true) + valueArray := make([]Value, deleteCount) + + for index := int64(0); index < deleteCount; index++ { + indexString := arrayIndexToString(int64(start + index)) + if thisObject.hasProperty(indexString) { + valueArray[index] = thisObject.get(indexString) + } + } + + // 0, <1, 2, 3, 4>, 5, 6, 7 + // a, b + // length 8 - delete 4 @ start 1 + + itemList := []Value{} + itemCount := int64(len(call.ArgumentList)) + if itemCount > 2 { + itemCount -= 2 // Less the first two arguments + itemList = call.ArgumentList[2:] + } else { + itemCount = 0 + } + if itemCount < deleteCount { + // The Object/Array is shrinking + stop := int64(length) - deleteCount + // The new length of the Object/Array before + // appending the itemList remainder + // Stopping at the lower bound of the insertion: + // Move an item from the after the deleted portion + // to a position after the inserted portion + for index := start; index < stop; index++ { + from := arrayIndexToString(index + deleteCount) // Position just after deletion + to := arrayIndexToString(index + itemCount) // Position just after splice (insertion) + if thisObject.hasProperty(from) { + thisObject.put(to, thisObject.get(from), true) + } else { + thisObject.delete(to, true) + } + } + // Delete off the end + // We don't bother to delete below (if any) since those + // will be overwritten anyway + for index := int64(length); index > (stop + itemCount); index-- { + thisObject.delete(arrayIndexToString(index-1), true) + } + } else if itemCount > deleteCount { + // The Object/Array is growing + // The itemCount is greater than the deleteCount, so we do + // not have to worry about overwriting what we should be moving + // --- + // Starting from the upper bound of the deletion: + // Move an item from the after the deleted portion + // to a position after the inserted portion + for index := int64(length) - deleteCount; index > start; index-- { + from := arrayIndexToString(index + deleteCount - 1) + to := arrayIndexToString(index + itemCount - 1) + if thisObject.hasProperty(from) { + thisObject.put(to, thisObject.get(from), true) + } else { + thisObject.delete(to, true) + } + } + } + + for index := int64(0); index < itemCount; index++ { + thisObject.put(arrayIndexToString(index+start), itemList[index], true) + } + thisObject.put("length", toValue_int64(int64(length)+itemCount-deleteCount), true) + + return toValue_object(call.runtime.newArrayOf(valueArray)) +} + +func builtinArray_slice(call FunctionCall) Value { + thisObject := call.thisObject() + + length := int64(toUint32(thisObject.get("length"))) + start, end := rangeStartEnd(call.ArgumentList, length, false) + + if start >= end { + // Always an empty array + return toValue_object(call.runtime.newArray(0)) + } + sliceLength := end - start + sliceValueArray := make([]Value, sliceLength) + + for index := int64(0); index < sliceLength; index++ { + from := arrayIndexToString(index + start) + if thisObject.hasProperty(from) { + sliceValueArray[index] = thisObject.get(from) + } + } + + return toValue_object(call.runtime.newArrayOf(sliceValueArray)) +} + +func builtinArray_unshift(call FunctionCall) Value { + thisObject := call.thisObject() + length := int64(toUint32(thisObject.get("length"))) + itemList := call.ArgumentList + itemCount := int64(len(itemList)) + + for index := length; index > 0; index-- { + from := arrayIndexToString(index - 1) + to := arrayIndexToString(index + itemCount - 1) + if thisObject.hasProperty(from) { + thisObject.put(to, thisObject.get(from), true) + } else { + thisObject.delete(to, true) + } + } + + for index := int64(0); index < itemCount; index++ { + thisObject.put(arrayIndexToString(index), itemList[index], true) + } + + newLength := toValue_int64(length + itemCount) + thisObject.put("length", newLength, true) + return newLength +} + +func builtinArray_reverse(call FunctionCall) Value { + thisObject := call.thisObject() + length := int64(toUint32(thisObject.get("length"))) + + lower := struct { + name string + index int64 + exists bool + }{} + upper := lower + + lower.index = 0 + middle := length / 2 // Division will floor + + for lower.index != middle { + lower.name = arrayIndexToString(lower.index) + upper.index = length - lower.index - 1 + upper.name = arrayIndexToString(upper.index) + + lower.exists = thisObject.hasProperty(lower.name) + upper.exists = thisObject.hasProperty(upper.name) + + if lower.exists && upper.exists { + lowerValue := thisObject.get(lower.name) + upperValue := thisObject.get(upper.name) + thisObject.put(lower.name, upperValue, true) + thisObject.put(upper.name, lowerValue, true) + } else if !lower.exists && upper.exists { + value := thisObject.get(upper.name) + thisObject.delete(upper.name, true) + thisObject.put(lower.name, value, true) + } else if lower.exists && !upper.exists { + value := thisObject.get(lower.name) + thisObject.delete(lower.name, true) + thisObject.put(upper.name, value, true) + } else { + // Nothing happens. + } + + lower.index += 1 + } + + return call.This +} + +func sortCompare(thisObject *_object, index0, index1 uint, compare *_object) int { + j := struct { + name string + exists bool + defined bool + value string + }{} + k := j + j.name = arrayIndexToString(int64(index0)) + j.exists = thisObject.hasProperty(j.name) + k.name = arrayIndexToString(int64(index1)) + k.exists = thisObject.hasProperty(k.name) + + if !j.exists && !k.exists { + return 0 + } else if !j.exists { + return 1 + } else if !k.exists { + return -1 + } + + x := thisObject.get(j.name) + y := thisObject.get(k.name) + j.defined = x.IsDefined() + k.defined = y.IsDefined() + + if !j.defined && !k.defined { + return 0 + } else if !j.defined { + return 1 + } else if !k.defined { + return -1 + } + + if compare == nil { + j.value = x.string() + k.value = y.string() + + if j.value == k.value { + return 0 + } else if j.value < k.value { + return -1 + } + + return 1 + } + + return int(toInt32(compare.call(Value{}, []Value{x, y}, false, nativeFrame))) +} + +func arraySortSwap(thisObject *_object, index0, index1 uint) { + + j := struct { + name string + exists bool + }{} + k := j + + j.name = arrayIndexToString(int64(index0)) + j.exists = thisObject.hasProperty(j.name) + k.name = arrayIndexToString(int64(index1)) + k.exists = thisObject.hasProperty(k.name) + + if j.exists && k.exists { + jValue := thisObject.get(j.name) + kValue := thisObject.get(k.name) + thisObject.put(j.name, kValue, true) + thisObject.put(k.name, jValue, true) + } else if !j.exists && k.exists { + value := thisObject.get(k.name) + thisObject.delete(k.name, true) + thisObject.put(j.name, value, true) + } else if j.exists && !k.exists { + value := thisObject.get(j.name) + thisObject.delete(j.name, true) + thisObject.put(k.name, value, true) + } else { + // Nothing happens. + } +} + +func arraySortQuickPartition(thisObject *_object, left, right, pivot uint, compare *_object) uint { + arraySortSwap(thisObject, pivot, right) // Right is now the pivot value + cursor := left + for index := left; index < right; index++ { + if sortCompare(thisObject, index, right, compare) == -1 { // Compare to the pivot value + arraySortSwap(thisObject, index, cursor) + cursor += 1 + } + } + arraySortSwap(thisObject, cursor, right) + return cursor +} + +func arraySortQuickSort(thisObject *_object, left, right uint, compare *_object) { + if left < right { + pivot := left + (right-left)/2 + pivot = arraySortQuickPartition(thisObject, left, right, pivot, compare) + if pivot > 0 { + arraySortQuickSort(thisObject, left, pivot-1, compare) + } + arraySortQuickSort(thisObject, pivot+1, right, compare) + } +} + +func builtinArray_sort(call FunctionCall) Value { + thisObject := call.thisObject() + length := uint(toUint32(thisObject.get("length"))) + compareValue := call.Argument(0) + compare := compareValue._object() + if compareValue.IsUndefined() { + } else if !compareValue.isCallable() { + panic(call.runtime.panicTypeError()) + } + if length > 1 { + arraySortQuickSort(thisObject, 0, length-1, compare) + } + return call.This +} + +func builtinArray_isArray(call FunctionCall) Value { + return toValue_bool(isArray(call.Argument(0)._object())) +} + +func builtinArray_indexOf(call FunctionCall) Value { + thisObject, matchValue := call.thisObject(), call.Argument(0) + if length := int64(toUint32(thisObject.get("length"))); length > 0 { + index := int64(0) + if len(call.ArgumentList) > 1 { + index = call.Argument(1).number().int64 + } + if index < 0 { + if index += length; index < 0 { + index = 0 + } + } else if index >= length { + index = -1 + } + for ; index >= 0 && index < length; index++ { + name := arrayIndexToString(int64(index)) + if !thisObject.hasProperty(name) { + continue + } + value := thisObject.get(name) + if strictEqualityComparison(matchValue, value) { + return toValue_uint32(uint32(index)) + } + } + } + return toValue_int(-1) +} + +func builtinArray_lastIndexOf(call FunctionCall) Value { + thisObject, matchValue := call.thisObject(), call.Argument(0) + length := int64(toUint32(thisObject.get("length"))) + index := length - 1 + if len(call.ArgumentList) > 1 { + index = call.Argument(1).number().int64 + } + if 0 > index { + index += length + } + if index > length { + index = length - 1 + } else if 0 > index { + return toValue_int(-1) + } + for ; index >= 0; index-- { + name := arrayIndexToString(int64(index)) + if !thisObject.hasProperty(name) { + continue + } + value := thisObject.get(name) + if strictEqualityComparison(matchValue, value) { + return toValue_uint32(uint32(index)) + } + } + return toValue_int(-1) +} + +func builtinArray_every(call FunctionCall) Value { + thisObject := call.thisObject() + this := toValue_object(thisObject) + if iterator := call.Argument(0); iterator.isCallable() { + length := int64(toUint32(thisObject.get("length"))) + 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(call.runtime, callThis, value, toValue_int64(index), this).bool() { + continue + } + return falseValue + } + } + return trueValue + } + panic(call.runtime.panicTypeError()) +} + +func builtinArray_some(call FunctionCall) Value { + thisObject := call.thisObject() + this := toValue_object(thisObject) + if iterator := call.Argument(0); iterator.isCallable() { + length := int64(toUint32(thisObject.get("length"))) + 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(call.runtime, callThis, value, toValue_int64(index), this).bool() { + return trueValue + } + } + } + return falseValue + } + panic(call.runtime.panicTypeError()) +} + +func builtinArray_forEach(call FunctionCall) Value { + thisObject := call.thisObject() + this := toValue_object(thisObject) + if iterator := call.Argument(0); iterator.isCallable() { + length := int64(toUint32(thisObject.get("length"))) + callThis := call.Argument(1) + for index := int64(0); index < length; index++ { + if key := arrayIndexToString(index); thisObject.hasProperty(key) { + iterator.call(call.runtime, callThis, thisObject.get(key), toValue_int64(index), this) + } + } + return Value{} + } + panic(call.runtime.panicTypeError()) +} + +func builtinArray_map(call FunctionCall) Value { + thisObject := call.thisObject() + this := toValue_object(thisObject) + if iterator := call.Argument(0); iterator.isCallable() { + length := int64(toUint32(thisObject.get("length"))) + callThis := call.Argument(1) + values := make([]Value, length) + for index := int64(0); index < length; index++ { + if key := arrayIndexToString(index); thisObject.hasProperty(key) { + values[index] = iterator.call(call.runtime, callThis, thisObject.get(key), index, this) + } else { + values[index] = Value{} + } + } + return toValue_object(call.runtime.newArrayOf(values)) + } + panic(call.runtime.panicTypeError()) +} + +func builtinArray_filter(call FunctionCall) Value { + thisObject := call.thisObject() + this := toValue_object(thisObject) + if iterator := call.Argument(0); iterator.isCallable() { + length := int64(toUint32(thisObject.get("length"))) + callThis := call.Argument(1) + values := make([]Value, 0) + for index := int64(0); index < length; index++ { + if key := arrayIndexToString(index); thisObject.hasProperty(key) { + value := thisObject.get(key) + if iterator.call(call.runtime, callThis, value, index, this).bool() { + values = append(values, value) + } + } + } + return toValue_object(call.runtime.newArrayOf(values)) + } + panic(call.runtime.panicTypeError()) +} + +func builtinArray_reduce(call FunctionCall) Value { + thisObject := call.thisObject() + this := toValue_object(thisObject) + if iterator := call.Argument(0); iterator.isCallable() { + initial := len(call.ArgumentList) > 1 + start := call.Argument(1) + length := int64(toUint32(thisObject.get("length"))) + index := int64(0) + if length > 0 || initial { + var accumulator Value + if !initial { + for ; index < length; index++ { + if key := arrayIndexToString(index); thisObject.hasProperty(key) { + accumulator = thisObject.get(key) + index++ + break + } + } + } else { + accumulator = start + } + for ; index < length; index++ { + if key := arrayIndexToString(index); thisObject.hasProperty(key) { + accumulator = iterator.call(call.runtime, Value{}, accumulator, thisObject.get(key), key, this) + } + } + return accumulator + } + } + panic(call.runtime.panicTypeError()) +} + +func builtinArray_reduceRight(call FunctionCall) Value { + thisObject := call.thisObject() + this := toValue_object(thisObject) + if iterator := call.Argument(0); iterator.isCallable() { + initial := len(call.ArgumentList) > 1 + start := call.Argument(1) + length := int64(toUint32(thisObject.get("length"))) + if length > 0 || initial { + index := length - 1 + var accumulator Value + if !initial { + for ; index >= 0; index-- { + if key := arrayIndexToString(index); thisObject.hasProperty(key) { + accumulator = thisObject.get(key) + index -= 1 + break + } + } + } else { + accumulator = start + } + for ; index >= 0; index-- { + if key := arrayIndexToString(index); thisObject.hasProperty(key) { + accumulator = iterator.call(call.runtime, Value{}, accumulator, thisObject.get(key), key, this) + } + } + return accumulator + } + } + panic(call.runtime.panicTypeError()) +} diff --git a/vendor/github.com/robertkrimen/otto/builtin_boolean.go b/vendor/github.com/robertkrimen/otto/builtin_boolean.go new file mode 100644 index 0000000..59b8e78 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_boolean.go @@ -0,0 +1,28 @@ +package otto + +// Boolean + +func builtinBoolean(call FunctionCall) Value { + return toValue_bool(call.Argument(0).bool()) +} + +func builtinNewBoolean(self *_object, argumentList []Value) Value { + return toValue_object(self.runtime.newBoolean(valueOfArrayIndex(argumentList, 0))) +} + +func builtinBoolean_toString(call FunctionCall) Value { + value := call.This + if !value.IsBoolean() { + // Will throw a TypeError if ThisObject is not a Boolean + value = call.thisClassObject("Boolean").primitiveValue() + } + return toValue_string(value.string()) +} + +func builtinBoolean_valueOf(call FunctionCall) Value { + value := call.This + if !value.IsBoolean() { + value = call.thisClassObject("Boolean").primitiveValue() + } + return value +} diff --git a/vendor/github.com/robertkrimen/otto/builtin_date.go b/vendor/github.com/robertkrimen/otto/builtin_date.go new file mode 100644 index 0000000..f20bf8e --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_date.go @@ -0,0 +1,615 @@ +package otto + +import ( + "math" + Time "time" +) + +// Date + +const ( + // TODO Be like V8? + // builtinDate_goDateTimeLayout = "Mon Jan 2 2006 15:04:05 GMT-0700 (MST)" + builtinDate_goDateTimeLayout = Time.RFC1123 // "Mon, 02 Jan 2006 15:04:05 MST" + builtinDate_goDateLayout = "Mon, 02 Jan 2006" + builtinDate_goTimeLayout = "15:04:05 MST" +) + +func builtinDate(call FunctionCall) Value { + date := &_dateObject{} + date.Set(newDateTime([]Value{}, Time.Local)) + return toValue_string(date.Time().Format(builtinDate_goDateTimeLayout)) +} + +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.runtime, call.thisObject()) + if date.isNaN { + return toValue_string("Invalid Date") + } + return toValue_string(date.Time().Local().Format(builtinDate_goDateTimeLayout)) +} + +func builtinDate_toDateString(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return toValue_string("Invalid Date") + } + return toValue_string(date.Time().Local().Format(builtinDate_goDateLayout)) +} + +func builtinDate_toTimeString(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return toValue_string("Invalid Date") + } + return toValue_string(date.Time().Local().Format(builtinDate_goTimeLayout)) +} + +func builtinDate_toUTCString(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return toValue_string("Invalid Date") + } + return toValue_string(date.Time().Format(builtinDate_goDateTimeLayout)) +} + +func builtinDate_toISOString(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return toValue_string("Invalid Date") + } + return toValue_string(date.Time().Format("2006-01-02T15:04:05.000Z")) +} + +func builtinDate_toJSON(call FunctionCall) Value { + object := call.thisObject() + value := object.DefaultValue(defaultValueHintNumber) // FIXME object.primitiveNumberValue + { // FIXME value.isFinite + value := value.float64() + if math.IsNaN(value) || math.IsInf(value, 0) { + return nullValue + } + } + toISOString := object.get("toISOString") + if !toISOString.isCallable() { + // FIXME + panic(call.runtime.panicTypeError()) + } + return toISOString.call(call.runtime, toValue_object(object), []Value{}) +} + +func builtinDate_toGMTString(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return toValue_string("Invalid Date") + } + return toValue_string(date.Time().Format("Mon, 02 Jan 2006 15:04:05 GMT")) +} + +func builtinDate_getTime(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + // We do this (convert away from a float) so the user + // does not get something back in exponential notation + return toValue_int64(int64(date.Epoch())) +} + +func builtinDate_setTime(call FunctionCall) Value { + object := call.thisObject() + 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(call.runtime, call.thisObject()) + if date.isNaN { + return nil, nil, nil, nil + } + + if argumentLimit > len(call.ArgumentList) { + argumentLimit = len(call.ArgumentList) + } + + if argumentLimit == 0 { + object.value = invalidDateObject + return nil, nil, nil, nil + } + + valueList := make([]int, argumentLimit) + for index := 0; index < argumentLimit; index++ { + value := call.ArgumentList[index] + nm := value.number() + switch nm.kind { + case numberInteger, numberFloat: + default: + object.value = invalidDateObject + return nil, nil, nil, nil + } + valueList[index] = int(nm.int64) + } + baseTime := date.Time() + if timeLocal { + baseTime = baseTime.Local() + } + ecmaTime := ecmaTime(baseTime) + return object, &date, &ecmaTime, valueList +} + +func builtinDate_parse(call FunctionCall) Value { + date := call.Argument(0).string() + return toValue_float64(dateParse(date)) +} + +func builtinDate_UTC(call FunctionCall) Value { + return toValue_float64(newDateTime(call.ArgumentList, Time.UTC)) +} + +func builtinDate_now(call FunctionCall) Value { + call.ArgumentList = []Value(nil) + return builtinDate_UTC(call) +} + +// This is a placeholder +func builtinDate_toLocaleString(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return toValue_string("Invalid Date") + } + return toValue_string(date.Time().Local().Format("2006-01-02 15:04:05")) +} + +// This is a placeholder +func builtinDate_toLocaleDateString(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return toValue_string("Invalid Date") + } + return toValue_string(date.Time().Local().Format("2006-01-02")) +} + +// This is a placeholder +func builtinDate_toLocaleTimeString(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return toValue_string("Invalid Date") + } + return toValue_string(date.Time().Local().Format("15:04:05")) +} + +func builtinDate_valueOf(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return date.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.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Local().Year() - 1900) +} + +func builtinDate_getFullYear(call FunctionCall) Value { + // Will throw a TypeError is ThisObject is nil or + // does not have Class of "Date" + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Local().Year()) +} + +func builtinDate_getUTCFullYear(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Year()) +} + +func builtinDate_getMonth(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(dateFromGoMonth(date.Time().Local().Month())) +} + +func builtinDate_getUTCMonth(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(dateFromGoMonth(date.Time().Month())) +} + +func builtinDate_getDate(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Local().Day()) +} + +func builtinDate_getUTCDate(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Day()) +} + +func builtinDate_getDay(call FunctionCall) Value { + // Actually day of the week + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(dateFromGoDay(date.Time().Local().Weekday())) +} + +func builtinDate_getUTCDay(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(dateFromGoDay(date.Time().Weekday())) +} + +func builtinDate_getHours(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Local().Hour()) +} + +func builtinDate_getUTCHours(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Hour()) +} + +func builtinDate_getMinutes(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Local().Minute()) +} + +func builtinDate_getUTCMinutes(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Minute()) +} + +func builtinDate_getSeconds(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Local().Second()) +} + +func builtinDate_getUTCSeconds(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Second()) +} + +func builtinDate_getMilliseconds(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Local().Nanosecond() / (100 * 100 * 100)) +} + +func builtinDate_getUTCMilliseconds(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + return toValue_int(date.Time().Nanosecond() / (100 * 100 * 100)) +} + +func builtinDate_getTimezoneOffset(call FunctionCall) Value { + date := dateObjectOf(call.runtime, call.thisObject()) + if date.isNaN { + return NaNValue() + } + timeLocal := date.Time().Local() + // Is this kosher? + timeLocalAsUTC := Time.Date( + timeLocal.Year(), + timeLocal.Month(), + timeLocal.Day(), + timeLocal.Hour(), + timeLocal.Minute(), + timeLocal.Second(), + timeLocal.Nanosecond(), + Time.UTC, + ) + return toValue_float64(date.Time().Sub(timeLocalAsUTC).Seconds() / 60) +} + +func builtinDate_setMilliseconds(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 1, true) + if ecmaTime == nil { + return NaNValue() + } + + ecmaTime.millisecond = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setUTCMilliseconds(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 1, false) + if ecmaTime == nil { + return NaNValue() + } + + ecmaTime.millisecond = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setSeconds(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 2, true) + if ecmaTime == nil { + return NaNValue() + } + + if len(value) > 1 { + ecmaTime.millisecond = value[1] + } + ecmaTime.second = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setUTCSeconds(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 2, false) + if ecmaTime == nil { + return NaNValue() + } + + if len(value) > 1 { + ecmaTime.millisecond = value[1] + } + ecmaTime.second = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setMinutes(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 3, true) + if ecmaTime == nil { + return NaNValue() + } + + if len(value) > 2 { + ecmaTime.millisecond = value[2] + ecmaTime.second = value[1] + } else if len(value) > 1 { + ecmaTime.second = value[1] + } + ecmaTime.minute = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setUTCMinutes(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 3, false) + if ecmaTime == nil { + return NaNValue() + } + + if len(value) > 2 { + ecmaTime.millisecond = value[2] + ecmaTime.second = value[1] + } else if len(value) > 1 { + ecmaTime.second = value[1] + } + ecmaTime.minute = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setHours(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 4, true) + if ecmaTime == nil { + return NaNValue() + } + + if len(value) > 3 { + ecmaTime.millisecond = value[3] + ecmaTime.second = value[2] + ecmaTime.minute = value[1] + } else if len(value) > 2 { + ecmaTime.second = value[2] + ecmaTime.minute = value[1] + } else if len(value) > 1 { + ecmaTime.minute = value[1] + } + ecmaTime.hour = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setUTCHours(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 4, false) + if ecmaTime == nil { + return NaNValue() + } + + if len(value) > 3 { + ecmaTime.millisecond = value[3] + ecmaTime.second = value[2] + ecmaTime.minute = value[1] + } else if len(value) > 2 { + ecmaTime.second = value[2] + ecmaTime.minute = value[1] + } else if len(value) > 1 { + ecmaTime.minute = value[1] + } + ecmaTime.hour = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setDate(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 1, true) + if ecmaTime == nil { + return NaNValue() + } + + ecmaTime.day = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setUTCDate(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 1, false) + if ecmaTime == nil { + return NaNValue() + } + + ecmaTime.day = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setMonth(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 2, true) + if ecmaTime == nil { + return NaNValue() + } + + if len(value) > 1 { + ecmaTime.day = value[1] + } + ecmaTime.month = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setUTCMonth(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 2, false) + if ecmaTime == nil { + return NaNValue() + } + + if len(value) > 1 { + ecmaTime.day = value[1] + } + ecmaTime.month = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setYear(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 1, true) + if ecmaTime == nil { + return NaNValue() + } + + year := value[0] + if 0 <= year && year <= 99 { + year += 1900 + } + ecmaTime.year = year + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setFullYear(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 3, true) + if ecmaTime == nil { + return NaNValue() + } + + if len(value) > 2 { + ecmaTime.day = value[2] + ecmaTime.month = value[1] + } else if len(value) > 1 { + ecmaTime.month = value[1] + } + ecmaTime.year = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +func builtinDate_setUTCFullYear(call FunctionCall) Value { + object, date, ecmaTime, value := _builtinDate_beforeSet(call, 3, false) + if ecmaTime == nil { + return NaNValue() + } + + if len(value) > 2 { + ecmaTime.day = value[2] + ecmaTime.month = value[1] + } else if len(value) > 1 { + ecmaTime.month = value[1] + } + ecmaTime.year = value[0] + + date.SetTime(ecmaTime.goTime()) + object.value = *date + return date.Value() +} + +// toUTCString +// toISOString +// toJSONString +// toJSON diff --git a/vendor/github.com/robertkrimen/otto/builtin_error.go b/vendor/github.com/robertkrimen/otto/builtin_error.go new file mode 100644 index 0000000..4c054fb --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_error.go @@ -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))) +} diff --git a/vendor/github.com/robertkrimen/otto/builtin_function.go b/vendor/github.com/robertkrimen/otto/builtin_function.go new file mode 100644 index 0000000..3d07566 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_function.go @@ -0,0 +1,129 @@ +package otto + +import ( + "fmt" + "regexp" + "strings" + "unicode" + + "github.com/robertkrimen/otto/parser" +) + +// Function + +func builtinFunction(call FunctionCall) Value { + return toValue_object(builtinNewFunctionNative(call.runtime, call.ArgumentList)) +} + +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(value.string(), func(chr rune) bool { + return chr == ',' || unicode.IsSpace(chr) + }) + parameterList = append(parameterList, tmp...) + } + return parameterList +} + +var matchIdentifier = regexp.MustCompile(`^[$_\p{L}][$_\p{L}\d}]*$`) + +func builtinNewFunctionNative(runtime *_runtime, argumentList []Value) *_object { + var parameterList, body string + count := len(argumentList) + if count > 0 { + tmp := make([]string, 0, count-1) + for _, value := range argumentList[0 : count-1] { + tmp = append(tmp, value.string()) + } + parameterList = strings.Join(tmp, ",") + body = argumentList[count-1].string() + } + + // FIXME + function, err := parser.ParseFunction(parameterList, body) + runtime.parseThrow(err) // Will panic/throw appropriately + cmpl := _compiler{} + cmpl_function := cmpl.parseExpression(function) + + return runtime.newNodeFunction(cmpl_function.(*_nodeFunctionLiteral), runtime.globalStash) +} + +func builtinFunction_toString(call FunctionCall) Value { + object := call.thisClassObject("Function") // Should throw a TypeError unless Function + 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(call.runtime.panicTypeError()) + } + this := call.Argument(0) + if this.IsUndefined() { + // FIXME Not ECMA5 + this = toValue_object(call.runtime.globalObject) + } + argumentList := call.Argument(1) + switch argumentList.kind { + case valueUndefined, valueNull: + return call.thisObject().call(this, nil, false, nativeFrame) + case valueObject: + default: + panic(call.runtime.panicTypeError()) + } + + arrayObject := argumentList._object() + thisObject := call.thisObject() + length := int64(toUint32(arrayObject.get("length"))) + valueArray := make([]Value, length) + for index := int64(0); index < length; index++ { + valueArray[index] = arrayObject.get(arrayIndexToString(index)) + } + return thisObject.call(this, valueArray, false, nativeFrame) +} + +func builtinFunction_call(call FunctionCall) Value { + if !call.This.isCallable() { + panic(call.runtime.panicTypeError()) + } + thisObject := call.thisObject() + this := call.Argument(0) + if this.IsUndefined() { + // FIXME Not ECMA5 + this = toValue_object(call.runtime.globalObject) + } + if len(call.ArgumentList) >= 1 { + return thisObject.call(this, call.ArgumentList[1:], false, nativeFrame) + } + return thisObject.call(this, nil, false, nativeFrame) +} + +func builtinFunction_bind(call FunctionCall) Value { + target := call.This + if !target.isCallable() { + panic(call.runtime.panicTypeError()) + } + targetObject := target._object() + + this := call.Argument(0) + argumentList := call.slice(1) + if this.IsUndefined() { + // FIXME Do this elsewhere? + this = toValue_object(call.runtime.globalObject) + } + + return toValue_object(call.runtime.newBoundFunction(targetObject, this, argumentList)) +} diff --git a/vendor/github.com/robertkrimen/otto/builtin_json.go b/vendor/github.com/robertkrimen/otto/builtin_json.go new file mode 100644 index 0000000..aed54bf --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_json.go @@ -0,0 +1,299 @@ +package otto + +import ( + "bytes" + "encoding/json" + "fmt" + "strings" +) + +type _builtinJSON_parseContext struct { + call FunctionCall + reviver Value +} + +func builtinJSON_parse(call FunctionCall) Value { + ctx := _builtinJSON_parseContext{ + call: call, + } + revive := false + if reviver := call.Argument(1); reviver.isCallable() { + revive = true + ctx.reviver = reviver + } + + var root interface{} + err := json.Unmarshal([]byte(call.Argument(0).string()), &root) + if err != nil { + panic(call.runtime.panicSyntaxError(err.Error())) + } + value, exists := builtinJSON_parseWalk(ctx, root) + if !exists { + value = Value{} + } + if revive { + root := ctx.call.runtime.newObject() + root.put("", value, false) + return builtinJSON_reviveWalk(ctx, root, "") + } + return value +} + +func builtinJSON_reviveWalk(ctx _builtinJSON_parseContext, holder *_object, name string) Value { + value := holder.get(name) + if object := value._object(); object != nil { + if isArray(object) { + length := int64(objectLength(object)) + for index := int64(0); index < length; index += 1 { + name := arrayIndexToString(index) + value := builtinJSON_reviveWalk(ctx, object, name) + if value.IsUndefined() { + object.delete(name, false) + } else { + object.defineProperty(name, value, 0111, false) + } + } + } else { + object.enumerate(false, func(name string) bool { + value := builtinJSON_reviveWalk(ctx, object, name) + if value.IsUndefined() { + object.delete(name, false) + } else { + object.defineProperty(name, value, 0111, false) + } + return true + }) + } + } + 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 + case bool: + return toValue_bool(value), true + case string: + return toValue_string(value), true + case float64: + return toValue_float64(value), true + case []interface{}: + arrayValue := make([]Value, len(value)) + for index, rawValue := range value { + if value, exists := builtinJSON_parseWalk(ctx, rawValue); exists { + arrayValue[index] = value + } + } + return toValue_object(ctx.call.runtime.newArrayOf(arrayValue)), true + case map[string]interface{}: + object := ctx.call.runtime.newObject() + for name, rawValue := range value { + if value, exists := builtinJSON_parseWalk(ctx, rawValue); exists { + object.put(name, value, false) + } + } + return toValue_object(object), true + } + return Value{}, false +} + +type _builtinJSON_stringifyContext struct { + call FunctionCall + stack []*_object + propertyList []string + replacerFunction *Value + gap string +} + +func builtinJSON_stringify(call FunctionCall) Value { + ctx := _builtinJSON_stringifyContext{ + call: call, + stack: []*_object{nil}, + } + replacer := call.Argument(1)._object() + if replacer != nil { + if isArray(replacer) { + length := objectLength(replacer) + seen := map[string]bool{} + propertyList := make([]string, length) + length = 0 + for index, _ := range propertyList { + value := replacer.get(arrayIndexToString(int64(index))) + switch value.kind { + case valueObject: + switch value.value.(*_object).class { + case "String": + case "Number": + default: + continue + } + case valueString: + case valueNumber: + default: + continue + } + name := value.string() + if seen[name] { + continue + } + seen[name] = true + length += 1 + propertyList[index] = name + } + ctx.propertyList = propertyList[0:length] + } else if replacer.class == "Function" { + value := toValue_object(replacer) + ctx.replacerFunction = &value + } + } + if spaceValue, exists := call.getArgument(2); exists { + if spaceValue.kind == valueObject { + switch spaceValue.value.(*_object).class { + case "String": + spaceValue = toValue_string(spaceValue.string()) + case "Number": + spaceValue = spaceValue.numberValue() + } + } + switch spaceValue.kind { + case valueString: + value := spaceValue.string() + if len(value) > 10 { + ctx.gap = value[0:10] + } else { + ctx.gap = value + } + case valueNumber: + value := spaceValue.number().int64 + if value > 10 { + value = 10 + } else if value < 0 { + value = 0 + } + ctx.gap = strings.Repeat(" ", int(value)) + } + } + holder := call.runtime.newObject() + holder.put("", call.Argument(0), false) + value, exists := builtinJSON_stringifyWalk(ctx, "", holder) + if !exists { + return Value{} + } + valueJSON, err := json.Marshal(value) + if err != nil { + panic(call.runtime.panicTypeError(err.Error())) + } + if ctx.gap != "" { + valueJSON1 := bytes.Buffer{} + json.Indent(&valueJSON1, valueJSON, "", ctx.gap) + valueJSON = valueJSON1.Bytes() + } + return toValue_string(string(valueJSON)) +} + +func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, holder *_object) (interface{}, bool) { + value := holder.get(key) + + if value.IsObject() { + object := value._object() + if toJSON := object.get("toJSON"); toJSON.IsFunction() { + 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 { + marshaler := object.objectClass.marshalJSON(object) + if marshaler != nil { + return marshaler, true + } + } + } + } + + if ctx.replacerFunction != nil { + value = (*ctx.replacerFunction).call(ctx.call.runtime, toValue_object(holder), key, value) + } + + if value.kind == valueObject { + switch value.value.(*_object).class { + case "Boolean": + value = value._object().value.(Value) + case "String": + value = toValue_string(value.string()) + case "Number": + value = value.numberValue() + } + } + + switch value.kind { + case valueBoolean: + return value.bool(), true + case valueString: + return value.string(), true + case valueNumber: + integer := value.number() + switch integer.kind { + case numberInteger: + return integer.int64, true + case numberFloat: + return integer.float64, true + default: + return nil, true + } + case valueNull: + return nil, true + case valueObject: + holder := value._object() + if value := value._object(); nil != value { + for _, object := range ctx.stack { + if holder == object { + 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) { + 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)) + value, _ := builtinJSON_stringifyWalk(ctx, name, holder) + array[index] = value + } + return array, true + } else if holder.class != "Function" { + object := map[string]interface{}{} + if ctx.propertyList != nil { + for _, name := range ctx.propertyList { + value, exists := builtinJSON_stringifyWalk(ctx, name, holder) + if exists { + object[name] = value + } + } + } else { + // Go maps are without order, so this doesn't conform to the ECMA ordering + // standard, but oh well... + holder.enumerate(false, func(name string) bool { + value, exists := builtinJSON_stringifyWalk(ctx, name, holder) + if exists { + object[name] = value + } + return true + }) + } + return object, true + } + } + return nil, false +} diff --git a/vendor/github.com/robertkrimen/otto/builtin_math.go b/vendor/github.com/robertkrimen/otto/builtin_math.go new file mode 100644 index 0000000..a9f4a55 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_math.go @@ -0,0 +1,145 @@ +package otto + +import ( + "math" + "math/rand" +) + +// Math + +func builtinMath_abs(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Abs(number)) +} + +func builtinMath_acos(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Acos(number)) +} + +func builtinMath_asin(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Asin(number)) +} + +func builtinMath_atan(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Atan(number)) +} + +func builtinMath_atan2(call FunctionCall) Value { + y := call.Argument(0).float64() + if math.IsNaN(y) { + return NaNValue() + } + x := call.Argument(1).float64() + if math.IsNaN(x) { + return NaNValue() + } + return toValue_float64(math.Atan2(y, x)) +} + +func builtinMath_cos(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Cos(number)) +} + +func builtinMath_ceil(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Ceil(number)) +} + +func builtinMath_exp(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Exp(number)) +} + +func builtinMath_floor(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Floor(number)) +} + +func builtinMath_log(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Log(number)) +} + +func builtinMath_max(call FunctionCall) Value { + switch len(call.ArgumentList) { + case 0: + return negativeInfinityValue() + case 1: + return toValue_float64(call.ArgumentList[0].float64()) + } + result := call.ArgumentList[0].float64() + if math.IsNaN(result) { + return NaNValue() + } + for _, value := range call.ArgumentList[1:] { + value := value.float64() + if math.IsNaN(value) { + return NaNValue() + } + result = math.Max(result, value) + } + return toValue_float64(result) +} + +func builtinMath_min(call FunctionCall) Value { + switch len(call.ArgumentList) { + case 0: + return positiveInfinityValue() + case 1: + return toValue_float64(call.ArgumentList[0].float64()) + } + result := call.ArgumentList[0].float64() + if math.IsNaN(result) { + return NaNValue() + } + for _, value := range call.ArgumentList[1:] { + value := value.float64() + if math.IsNaN(value) { + return NaNValue() + } + result = math.Min(result, value) + } + return toValue_float64(result) +} + +func builtinMath_pow(call FunctionCall) Value { + // TODO Make sure this works according to the specification (15.8.2.13) + x := call.Argument(0).float64() + y := call.Argument(1).float64() + if math.Abs(x) == 1 && math.IsInf(y, 0) { + return NaNValue() + } + return toValue_float64(math.Pow(x, y)) +} + +func builtinMath_random(call FunctionCall) Value { + return toValue_float64(rand.Float64()) +} + +func builtinMath_round(call FunctionCall) Value { + number := call.Argument(0).float64() + value := math.Floor(number + 0.5) + if value == 0 { + value = math.Copysign(0, number) + } + return toValue_float64(value) +} + +func builtinMath_sin(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Sin(number)) +} + +func builtinMath_sqrt(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Sqrt(number)) +} + +func builtinMath_tan(call FunctionCall) Value { + number := call.Argument(0).float64() + return toValue_float64(math.Tan(number)) +} diff --git a/vendor/github.com/robertkrimen/otto/builtin_number.go b/vendor/github.com/robertkrimen/otto/builtin_number.go new file mode 100644 index 0000000..26a03e7 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_number.go @@ -0,0 +1,93 @@ +package otto + +import ( + "math" + "strconv" +) + +// Number + +func numberValueFromNumberArgumentList(argumentList []Value) Value { + if len(argumentList) > 0 { + return argumentList[0].numberValue() + } + return toValue_int(0) +} + +func builtinNumber(call FunctionCall) Value { + return numberValueFromNumberArgumentList(call.ArgumentList) +} + +func builtinNewNumber(self *_object, argumentList []Value) Value { + return toValue_object(self.runtime.newNumber(numberValueFromNumberArgumentList(argumentList))) +} + +func builtinNumber_toString(call FunctionCall) Value { + // Will throw a TypeError if ThisObject is not a Number + value := call.thisClassObject("Number").primitiveValue() + radix := 10 + radixArgument := call.Argument(0) + if radixArgument.IsDefined() { + integer := toIntegerFloat(radixArgument) + if integer < 2 || integer > 36 { + panic(call.runtime.panicRangeError("RangeError: toString() radix must be between 2 and 36")) + } + radix = int(integer) + } + if radix == 10 { + return toValue_string(value.string()) + } + return toValue_string(numberToStringRadix(value, radix)) +} + +func builtinNumber_valueOf(call FunctionCall) Value { + return call.thisClassObject("Number").primitiveValue() +} + +func builtinNumber_toFixed(call FunctionCall) Value { + precision := toIntegerFloat(call.Argument(0)) + if 20 < precision || 0 > precision { + panic(call.runtime.panicRangeError("toFixed() precision must be between 0 and 20")) + } + if call.This.IsNaN() { + return toValue_string("NaN") + } + value := call.This.float64() + if math.Abs(value) >= 1e21 { + return toValue_string(floatToString(value, 64)) + } + return toValue_string(strconv.FormatFloat(call.This.float64(), 'f', int(precision), 64)) +} + +func builtinNumber_toExponential(call FunctionCall) Value { + if call.This.IsNaN() { + return toValue_string("NaN") + } + precision := float64(-1) + if value := call.Argument(0); value.IsDefined() { + precision = toIntegerFloat(value) + if 0 > precision { + panic(call.runtime.panicRangeError("RangeError: toString() radix must be between 2 and 36")) + } + } + return toValue_string(strconv.FormatFloat(call.This.float64(), 'e', int(precision), 64)) +} + +func builtinNumber_toPrecision(call FunctionCall) Value { + if call.This.IsNaN() { + return toValue_string("NaN") + } + value := call.Argument(0) + if value.IsUndefined() { + return toValue_string(call.This.string()) + } + precision := toIntegerFloat(value) + if 1 > precision { + panic(call.runtime.panicRangeError("RangeError: toPrecision() precision must be greater than 1")) + } + return toValue_string(strconv.FormatFloat(call.This.float64(), 'g', int(precision), 64)) +} + +func builtinNumber_toLocaleString(call FunctionCall) Value { + return builtinNumber_toString(call) +} diff --git a/vendor/github.com/robertkrimen/otto/builtin_object.go b/vendor/github.com/robertkrimen/otto/builtin_object.go new file mode 100644 index 0000000..c2433f7 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_object.go @@ -0,0 +1,289 @@ +package otto + +import ( + "fmt" +) + +// Object + +func builtinObject(call FunctionCall) Value { + value := call.Argument(0) + switch value.kind { + case valueUndefined, valueNull: + return toValue_object(call.runtime.newObject()) + } + + return toValue_object(call.runtime.toObject(value)) +} + +func builtinNewObject(self *_object, argumentList []Value) Value { + value := valueOfArrayIndex(argumentList, 0) + switch value.kind { + case valueNull, valueUndefined: + case valueNumber, valueString, valueBoolean: + return toValue_object(self.runtime.toObject(value)) + case valueObject: + return value + default: + } + return toValue_object(self.runtime.newObject()) +} + +func builtinObject_valueOf(call FunctionCall) Value { + return toValue_object(call.thisObject()) +} + +func builtinObject_hasOwnProperty(call FunctionCall) Value { + propertyName := call.Argument(0).string() + thisObject := call.thisObject() + return toValue_bool(thisObject.hasOwnProperty(propertyName)) +} + +func builtinObject_isPrototypeOf(call FunctionCall) Value { + value := call.Argument(0) + if !value.IsObject() { + return falseValue + } + prototype := call.toObject(value).prototype + thisObject := call.thisObject() + for prototype != nil { + if thisObject == prototype { + return trueValue + } + prototype = prototype.prototype + } + return falseValue +} + +func builtinObject_propertyIsEnumerable(call FunctionCall) Value { + propertyName := call.Argument(0).string() + thisObject := call.thisObject() + property := thisObject.getOwnProperty(propertyName) + if property != nil && property.enumerable() { + return trueValue + } + return falseValue +} + +func builtinObject_toString(call FunctionCall) Value { + result := "" + if call.This.IsUndefined() { + result = "[object Undefined]" + } else if call.This.IsNull() { + result = "[object Null]" + } else { + result = fmt.Sprintf("[object %s]", call.thisObject().class) + } + return toValue_string(result) +} + +func builtinObject_toLocaleString(call FunctionCall) Value { + toString := call.thisObject().get("toString") + if !toString.isCallable() { + panic(call.runtime.panicTypeError()) + } + return toString.call(call.runtime, call.This) +} + +func builtinObject_getPrototypeOf(call FunctionCall) Value { + objectValue := call.Argument(0) + object := objectValue._object() + if object == nil { + panic(call.runtime.panicTypeError()) + } + + if object.prototype == nil { + return nullValue + } + + return toValue_object(object.prototype) +} + +func builtinObject_getOwnPropertyDescriptor(call FunctionCall) Value { + objectValue := call.Argument(0) + object := objectValue._object() + if object == nil { + panic(call.runtime.panicTypeError()) + } + + name := call.Argument(1).string() + descriptor := object.getOwnProperty(name) + if descriptor == nil { + return Value{} + } + return toValue_object(call.runtime.fromPropertyDescriptor(*descriptor)) +} + +func builtinObject_defineProperty(call FunctionCall) Value { + objectValue := call.Argument(0) + object := objectValue._object() + if object == nil { + panic(call.runtime.panicTypeError()) + } + name := call.Argument(1).string() + descriptor := toPropertyDescriptor(call.runtime, call.Argument(2)) + object.defineOwnProperty(name, descriptor, true) + return objectValue +} + +func builtinObject_defineProperties(call FunctionCall) Value { + objectValue := call.Argument(0) + object := objectValue._object() + if object == nil { + panic(call.runtime.panicTypeError()) + } + + properties := call.runtime.toObject(call.Argument(1)) + properties.enumerate(false, func(name string) bool { + descriptor := toPropertyDescriptor(call.runtime, properties.get(name)) + object.defineOwnProperty(name, descriptor, true) + return true + }) + + return objectValue +} + +func builtinObject_create(call FunctionCall) Value { + prototypeValue := call.Argument(0) + if !prototypeValue.IsNull() && !prototypeValue.IsObject() { + panic(call.runtime.panicTypeError()) + } + + object := call.runtime.newObject() + object.prototype = prototypeValue._object() + + propertiesValue := call.Argument(1) + if propertiesValue.IsDefined() { + properties := call.runtime.toObject(propertiesValue) + properties.enumerate(false, func(name string) bool { + descriptor := toPropertyDescriptor(call.runtime, properties.get(name)) + object.defineOwnProperty(name, descriptor, true) + return true + }) + } + + return toValue_object(object) +} + +func builtinObject_isExtensible(call FunctionCall) Value { + object := call.Argument(0) + if object := object._object(); object != nil { + return toValue_bool(object.extensible) + } + panic(call.runtime.panicTypeError()) +} + +func builtinObject_preventExtensions(call FunctionCall) Value { + object := call.Argument(0) + if object := object._object(); object != nil { + object.extensible = false + } else { + panic(call.runtime.panicTypeError()) + } + return object +} + +func builtinObject_isSealed(call FunctionCall) Value { + object := call.Argument(0) + if object := object._object(); object != nil { + if object.extensible { + return toValue_bool(false) + } + result := true + object.enumerate(true, func(name string) bool { + property := object.getProperty(name) + if property.configurable() { + result = false + } + return true + }) + return toValue_bool(result) + } + panic(call.runtime.panicTypeError()) +} + +func builtinObject_seal(call FunctionCall) Value { + object := call.Argument(0) + if object := object._object(); object != nil { + object.enumerate(true, func(name string) bool { + if property := object.getOwnProperty(name); nil != property && property.configurable() { + property.configureOff() + object.defineOwnProperty(name, *property, true) + } + return true + }) + object.extensible = false + } else { + panic(call.runtime.panicTypeError()) + } + return object +} + +func builtinObject_isFrozen(call FunctionCall) Value { + object := call.Argument(0) + if object := object._object(); object != nil { + if object.extensible { + return toValue_bool(false) + } + result := true + object.enumerate(true, func(name string) bool { + property := object.getProperty(name) + if property.configurable() || property.writable() { + result = false + } + return true + }) + return toValue_bool(result) + } + panic(call.runtime.panicTypeError()) +} + +func builtinObject_freeze(call FunctionCall) Value { + object := call.Argument(0) + if object := object._object(); object != nil { + object.enumerate(true, func(name string) bool { + if property, update := object.getOwnProperty(name), false; nil != property { + if property.isDataDescriptor() && property.writable() { + property.writeOff() + update = true + } + if property.configurable() { + property.configureOff() + update = true + } + if update { + object.defineOwnProperty(name, *property, true) + } + } + return true + }) + object.extensible = false + } else { + panic(call.runtime.panicTypeError()) + } + return object +} + +func builtinObject_keys(call FunctionCall) Value { + if object, keys := call.Argument(0)._object(), []Value(nil); nil != object { + object.enumerate(false, func(name string) bool { + keys = append(keys, toValue_string(name)) + return true + }) + return toValue_object(call.runtime.newArrayOf(keys)) + } + panic(call.runtime.panicTypeError()) +} + +func builtinObject_getOwnPropertyNames(call FunctionCall) Value { + if object, propertyNames := call.Argument(0)._object(), []Value(nil); nil != object { + object.enumerate(true, func(name string) bool { + if object.hasOwnProperty(name) { + propertyNames = append(propertyNames, toValue_string(name)) + } + return true + }) + return toValue_object(call.runtime.newArrayOf(propertyNames)) + } + panic(call.runtime.panicTypeError()) +} diff --git a/vendor/github.com/robertkrimen/otto/builtin_regexp.go b/vendor/github.com/robertkrimen/otto/builtin_regexp.go new file mode 100644 index 0000000..9942251 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_regexp.go @@ -0,0 +1,65 @@ +package otto + +import ( + "fmt" +) + +// RegExp + +func builtinRegExp(call FunctionCall) Value { + pattern := call.Argument(0) + flags := call.Argument(1) + if object := pattern._object(); object != nil { + if object.class == "RegExp" && flags.IsUndefined() { + return pattern + } + } + return toValue_object(call.runtime.newRegExp(pattern, flags)) +} + +func builtinNewRegExp(self *_object, argumentList []Value) Value { + return toValue_object(self.runtime.newRegExp( + valueOfArrayIndex(argumentList, 0), + valueOfArrayIndex(argumentList, 1), + )) +} + +func builtinRegExp_toString(call FunctionCall) Value { + thisObject := call.thisObject() + source := thisObject.get("source").string() + flags := []byte{} + if thisObject.get("global").bool() { + flags = append(flags, 'g') + } + if thisObject.get("ignoreCase").bool() { + flags = append(flags, 'i') + } + if thisObject.get("multiline").bool() { + flags = append(flags, 'm') + } + return toValue_string(fmt.Sprintf("/%s/%s", source, flags)) +} + +func builtinRegExp_exec(call FunctionCall) Value { + thisObject := call.thisObject() + target := call.Argument(0).string() + match, result := execRegExp(thisObject, target) + if !match { + return nullValue + } + return toValue_object(execResultToArray(call.runtime, target, result)) +} + +func builtinRegExp_test(call FunctionCall) Value { + thisObject := call.thisObject() + target := call.Argument(0).string() + match, _ := execRegExp(thisObject, target) + return toValue_bool(match) +} + +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 Value{} +} diff --git a/vendor/github.com/robertkrimen/otto/builtin_string.go b/vendor/github.com/robertkrimen/otto/builtin_string.go new file mode 100644 index 0000000..6a17184 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/builtin_string.go @@ -0,0 +1,500 @@ +package otto + +import ( + "bytes" + "regexp" + "strconv" + "strings" + "unicode/utf8" +) + +// String + +func stringValueFromStringArgumentList(argumentList []Value) Value { + if len(argumentList) > 0 { + return toValue_string(argumentList[0].string()) + } + return toValue_string("") +} + +func builtinString(call FunctionCall) Value { + return stringValueFromStringArgumentList(call.ArgumentList) +} + +func builtinNewString(self *_object, argumentList []Value) Value { + return toValue_object(self.runtime.newString(stringValueFromStringArgumentList(argumentList))) +} + +func builtinString_toString(call FunctionCall) Value { + return call.thisClassObject("String").primitiveValue() +} +func builtinString_valueOf(call FunctionCall) Value { + return call.thisClassObject("String").primitiveValue() +} + +func builtinString_fromCharCode(call FunctionCall) Value { + chrList := make([]uint16, len(call.ArgumentList)) + for index, value := range call.ArgumentList { + chrList[index] = toUint16(value) + } + return toValue_string16(chrList) +} + +func builtinString_charAt(call FunctionCall) 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("") + } + return toValue_string(string(chr)) +} + +func builtinString_charCodeAt(call FunctionCall) 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() + } + return toValue_uint16(uint16(chr)) +} + +func builtinString_concat(call FunctionCall) Value { + checkObjectCoercible(call.runtime, call.This) + var value bytes.Buffer + value.WriteString(call.This.string()) + for _, item := range call.ArgumentList { + value.WriteString(item.string()) + } + return toValue_string(value.String()) +} + +func builtinString_indexOf(call FunctionCall) Value { + 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)) + } + start := toIntegerFloat(call.Argument(1)) + if 0 > start { + start = 0 + } else if start >= float64(len(value)) { + if target == "" { + return toValue_int(len(value)) + } + return toValue_int(-1) + } + index := strings.Index(value[int(start):], target) + if index >= 0 { + index += int(start) + } + return toValue_int(index) +} + +func builtinString_lastIndexOf(call FunctionCall) Value { + 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)) + } + length := len(value) + if length == 0 { + return toValue_int(strings.LastIndex(value, target)) + } + 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.int64 { + start.int64 = 0 + } + end := int(start.int64) + len(target) + if end > length { + end = length + } + return toValue_int(strings.LastIndex(value[:end], target)) +} + +func builtinString_match(call FunctionCall) Value { + 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, Value{}) + } + global := matcher.get("global").bool() + if !global { + match, result := execRegExp(matcher, target) + if !match { + return nullValue + } + return toValue_object(execResultToArray(call.runtime, target, result)) + } + + { + result := matcher.regExpValue().regularExpression.FindAllStringIndex(target, -1) + matchCount := len(result) + if result == nil { + matcher.put("lastIndex", toValue_int(0), true) + return Value{} // !match + } + matchCount = len(result) + valueArray := make([]Value, matchCount) + for index := 0; index < matchCount; index++ { + valueArray[index] = toValue_string(target[result[index][0]:result[index][1]]) + } + matcher.put("lastIndex", toValue_int(result[matchCount-1][1]), true) + return toValue_object(call.runtime.newArrayOf(valueArray)) + } +} + +var builtinString_replace_Regexp = regexp.MustCompile("\\$(?:[\\$\\&\\'\\`1-9]|0[1-9]|[1-9][0-9])") + +func builtinString_findAndReplaceString(input []byte, lastIndex int, match []int, target []byte, replaceValue []byte) (output []byte) { + matchCount := len(match) / 2 + output = input + if match[0] != lastIndex { + output = append(output, target[lastIndex:match[0]]...) + } + replacement := builtinString_replace_Regexp.ReplaceAllFunc(replaceValue, func(part []byte) []byte { + // TODO Check if match[0] or match[1] can be -1 in this scenario + switch part[1] { + case '$': + return []byte{'$'} + case '&': + return target[match[0]:match[1]] + case '`': + return target[:match[0]] + case '\'': + return target[match[1]:len(target)] + } + matchNumberParse, error := strconv.ParseInt(string(part[1:]), 10, 64) + matchNumber := int(matchNumberParse) + if error != nil || matchNumber >= matchCount { + return []byte{} + } + offset := 2 * matchNumber + if match[offset] != -1 { + return target[match[offset]:match[offset+1]] + } + return []byte{} // The empty string + }) + output = append(output, replacement...) + return output +} + +func builtinString_replace(call FunctionCall) Value { + checkObjectCoercible(call.runtime, call.This) + target := []byte(call.This.string()) + searchValue := call.Argument(0) + searchObject := searchValue._object() + + // TODO If a capture is -1? + var search *regexp.Regexp + global := false + find := 1 + if searchValue.IsObject() && searchObject.class == "RegExp" { + regExp := searchObject.regExpValue() + search = regExp.regularExpression + if regExp.global { + find = -1 + } + } else { + search = regexp.MustCompile(regexp.QuoteMeta(searchValue.string())) + } + + found := search.FindAllSubmatchIndex(target, find) + if found == nil { + return toValue_string(string(target)) // !match + } + + { + lastIndex := 0 + result := []byte{} + + replaceValue := call.Argument(1) + if replaceValue.isCallable() { + target := string(target) + replace := replaceValue._object() + for _, match := range found { + if match[0] != lastIndex { + result = append(result, target[lastIndex:match[0]]...) + } + matchCount := len(match) / 2 + argumentList := make([]Value, matchCount+2) + for index := 0; index < matchCount; index++ { + offset := 2 * index + if match[offset] != -1 { + argumentList[index] = toValue_string(target[match[offset]:match[offset+1]]) + } else { + argumentList[index] = Value{} + } + } + argumentList[matchCount+0] = toValue_int(match[0]) + argumentList[matchCount+1] = toValue_string(target) + replacement := replace.call(Value{}, argumentList, false, nativeFrame).string() + result = append(result, []byte(replacement)...) + lastIndex = match[1] + } + + } else { + replace := []byte(replaceValue.string()) + for _, match := range found { + result = builtinString_findAndReplaceString(result, lastIndex, match, target, replace) + lastIndex = match[1] + } + } + + if lastIndex != len(target) { + result = append(result, target[lastIndex:]...) + } + + if global && searchObject != nil { + searchObject.put("lastIndex", toValue_int(lastIndex), true) + } + + return toValue_string(string(result)) + } +} + +func builtinString_search(call FunctionCall) Value { + 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, Value{}) + } + result := search.regExpValue().regularExpression.FindStringIndex(target) + if result == nil { + return toValue_int(-1) + } + return toValue_int(result[0]) +} + +func stringSplitMatch(target string, targetLength int64, index uint, search string, searchLength int64) (bool, uint) { + if int64(index)+searchLength > searchLength { + return false, 0 + } + found := strings.Index(target[index:], search) + if 0 > found { + return false, 0 + } + return true, uint(found) +} + +func builtinString_split(call FunctionCall) Value { + checkObjectCoercible(call.runtime, call.This) + target := call.This.string() + + separatorValue := call.Argument(0) + limitValue := call.Argument(1) + limit := -1 + if limitValue.IsDefined() { + limit = int(toUint32(limitValue)) + } + + if limit == 0 { + return toValue_object(call.runtime.newArray(0)) + } + + if separatorValue.IsUndefined() { + return toValue_object(call.runtime.newArrayOf([]Value{toValue_string(target)})) + } + + if separatorValue.isRegExp() { + targetLength := len(target) + search := separatorValue._object().regExpValue().regularExpression + valueArray := []Value{} + result := search.FindAllStringSubmatchIndex(target, -1) + lastIndex := 0 + found := 0 + + for _, match := range result { + if match[0] == match[1] { + // FIXME Ugh, this is a hack + if match[0] == 0 || match[0] == targetLength { + continue + } + } + + if lastIndex != match[0] { + valueArray = append(valueArray, toValue_string(target[lastIndex:match[0]])) + found++ + } else if lastIndex == match[0] { + if lastIndex != -1 { + valueArray = append(valueArray, toValue_string("")) + found++ + } + } + + lastIndex = match[1] + if found == limit { + goto RETURN + } + + captureCount := len(match) / 2 + for index := 1; index < captureCount; index++ { + offset := index * 2 + value := Value{} + if match[offset] != -1 { + value = toValue_string(target[match[offset]:match[offset+1]]) + } + valueArray = append(valueArray, value) + found++ + if found == limit { + goto RETURN + } + } + } + + if found != limit { + if lastIndex != targetLength { + valueArray = append(valueArray, toValue_string(target[lastIndex:targetLength])) + } else { + valueArray = append(valueArray, toValue_string("")) + } + } + + RETURN: + return toValue_object(call.runtime.newArrayOf(valueArray)) + + } else { + separator := separatorValue.string() + + splitLimit := limit + excess := false + if limit > 0 { + splitLimit = limit + 1 + excess = true + } + + split := strings.SplitN(target, separator, splitLimit) + + if excess && len(split) > limit { + split = split[:limit] + } + + valueArray := make([]Value, len(split)) + for index, value := range split { + valueArray[index] = toValue_string(value) + } + + return toValue_object(call.runtime.newArrayOf(valueArray)) + } +} + +func builtinString_slice(call FunctionCall) Value { + checkObjectCoercible(call.runtime, call.This) + target := call.This.string() + + length := int64(len(target)) + start, end := rangeStartEnd(call.ArgumentList, length, false) + if end-start <= 0 { + return toValue_string("") + } + return toValue_string(target[start:end]) +} + +func builtinString_substring(call FunctionCall) Value { + checkObjectCoercible(call.runtime, call.This) + target := call.This.string() + + length := int64(len(target)) + start, end := rangeStartEnd(call.ArgumentList, length, true) + if start > end { + start, end = end, start + } + return toValue_string(target[start:end]) +} + +func builtinString_substr(call FunctionCall) Value { + target := call.This.string() + + size := int64(len(target)) + start, length := rangeStartLength(call.ArgumentList, size) + + if start >= size { + return toValue_string("") + } + + if length <= 0 { + return toValue_string("") + } + + if start+length >= size { + // Cap length to be to the end of the string + // start = 3, length = 5, size = 4 [0, 1, 2, 3] + // 4 - 3 = 1 + // target[3:4] + length = size - start + } + + return toValue_string(target[start : start+length]) +} + +func builtinString_toLowerCase(call FunctionCall) Value { + checkObjectCoercible(call.runtime, call.This) + return toValue_string(strings.ToLower(call.This.string())) +} + +func builtinString_toUpperCase(call FunctionCall) Value { + 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.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.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.runtime, call.This) + return toValue(strings.TrimRight(call.This.string(), + builtinString_trim_whitespace)) +} + +func builtinString_localeCompare(call FunctionCall) Value { + 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 { + return toValue_int(0) + } + return toValue_int(1) +} + +/* +An alternate version of String.trim +func builtinString_trim(call FunctionCall) Value { + checkObjectCoercible(call.This) + return toValue_string(strings.TrimFunc(call.string(.This), isWhiteSpaceOrLineTerminator)) +} +*/ + +func builtinString_toLocaleLowerCase(call FunctionCall) Value { + return builtinString_toLowerCase(call) +} + +func builtinString_toLocaleUpperCase(call FunctionCall) Value { + return builtinString_toUpperCase(call) +} diff --git a/vendor/github.com/robertkrimen/otto/clone.go b/vendor/github.com/robertkrimen/otto/clone.go new file mode 100644 index 0000000..f79901b --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/clone.go @@ -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 +} diff --git a/vendor/github.com/robertkrimen/otto/cmpl.go b/vendor/github.com/robertkrimen/otto/cmpl.go new file mode 100644 index 0000000..c191b45 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/cmpl.go @@ -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) +} diff --git a/vendor/github.com/robertkrimen/otto/cmpl_evaluate.go b/vendor/github.com/robertkrimen/otto/cmpl_evaluate.go new file mode 100644 index 0000000..6741bf3 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/cmpl_evaluate.go @@ -0,0 +1,96 @@ +package otto + +import ( + "strconv" +) + +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, stash *_fnStash, node *_nodeFunctionLiteral, this Value, argumentList []Value) Value { + + indexOfParameterName := make([]string, len(argumentList)) + // function(abc, def, ghi) + // indexOfParameterName[0] = "abc" + // indexOfParameterName[1] = "def" + // indexOfParameterName[2] = "ghi" + // ... + + argumentsFound := false + for index, name := range node.parameterList { + if name == "arguments" { + argumentsFound = true + } + value := Value{} + if index < len(argumentList) { + value = argumentList[index] + indexOfParameterName[index] = name + } + // strict = false + self.scope.lexical.setValue(name, value, false) + } + + if !argumentsFound { + arguments := self.newArgumentsObject(indexOfParameterName, stash, len(argumentList)) + arguments.defineProperty("callee", toValue_object(function), 0101, false) + stash.arguments = arguments + // strict = false + self.scope.lexical.setValue("arguments", toValue_object(arguments), false) + for index, _ := range argumentList { + if index < len(node.parameterList) { + continue + } + indexAsString := strconv.FormatInt(int64(index), 10) + arguments.defineProperty(indexAsString, argumentList[index], 0111, false) + } + } + + self.cmpl_functionDeclaration(node.functionList) + self.cmpl_variableDeclaration(node.varList) + + result := self.cmpl_evaluate_nodeStatement(node.body) + if result.kind == valueResult { + return result + } + + return Value{} +} + +func (self *_runtime) cmpl_functionDeclaration(list []*_nodeFunctionLiteral) { + executionContext := self.scope + eval := executionContext.eval + stash := executionContext.variable + + for _, function := range list { + name := function.name + value := self.cmpl_evaluate_nodeExpression(function) + if !stash.hasBinding(name) { + stash.createBinding(name, eval == true, value) + } else { + // TODO 10.5.5.e + stash.setBinding(name, value, false) // TODO strict + } + } +} + +func (self *_runtime) cmpl_variableDeclaration(list []string) { + executionContext := self.scope + eval := executionContext.eval + stash := executionContext.variable + + for _, name := range list { + if !stash.hasBinding(name) { + stash.createBinding(name, eval == true, Value{}) // TODO strict? + } + } +} diff --git a/vendor/github.com/robertkrimen/otto/cmpl_evaluate_expression.go b/vendor/github.com/robertkrimen/otto/cmpl_evaluate_expression.go new file mode 100644 index 0000000..3444997 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/cmpl_evaluate_expression.go @@ -0,0 +1,456 @@ +package otto + +import ( + "fmt" + "math" + "runtime" + + "github.com/robertkrimen/otto/token" +) + +func (self *_runtime) cmpl_evaluate_nodeExpression(node _nodeExpression) Value { + // Allow interpreter interruption + // If the Interrupt channel is nil, then + // we avoid runtime.Gosched() overhead (if any) + // FIXME: Test this + if self.otto.Interrupt != nil { + runtime.Gosched() + select { + case value := <-self.otto.Interrupt: + value() + default: + } + } + + switch node := node.(type) { + + case *_nodeArrayLiteral: + return self.cmpl_evaluate_nodeArrayLiteral(node) + + case *_nodeAssignExpression: + return self.cmpl_evaluate_nodeAssignExpression(node) + + case *_nodeBinaryExpression: + if node.comparison { + return self.cmpl_evaluate_nodeBinaryExpression_comparison(node) + } else { + return self.cmpl_evaluate_nodeBinaryExpression(node) + } + + case *_nodeBracketExpression: + return self.cmpl_evaluate_nodeBracketExpression(node) + + case *_nodeCallExpression: + return self.cmpl_evaluate_nodeCallExpression(node, nil) + + case *_nodeConditionalExpression: + return self.cmpl_evaluate_nodeConditionalExpression(node) + + case *_nodeDotExpression: + return self.cmpl_evaluate_nodeDotExpression(node) + + case *_nodeFunctionLiteral: + var local = self.scope.lexical + if node.name != "" { + local = self.newDeclarationStash(local) + } + + value := toValue_object(self.newNodeFunction(node, local)) + if node.name != "" { + local.createBinding(node.name, false, value) + } + return value + + case *_nodeIdentifier: + name := node.name + // 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, self.scope.lexical, name, false, _at(node.idx)) + if reference == nil { + // Should never get here! + panic(hereBeDragons("referenceError == nil: " + name)) + } + return toValue(reference) + + case *_nodeLiteral: + return node.value + + case *_nodeNewExpression: + return self.cmpl_evaluate_nodeNewExpression(node) + + case *_nodeObjectLiteral: + return self.cmpl_evaluate_nodeObjectLiteral(node) + + case *_nodeRegExpLiteral: + return toValue_object(self._newRegExp(node.pattern, node.flags)) + + case *_nodeSequenceExpression: + return self.cmpl_evaluate_nodeSequenceExpression(node) + + case *_nodeThisExpression: + return toValue_object(self.scope.this) + + case *_nodeUnaryExpression: + return self.cmpl_evaluate_nodeUnaryExpression(node) + + case *_nodeVariableExpression: + return self.cmpl_evaluate_nodeVariableExpression(node) + } + + panic(fmt.Errorf("Here be dragons: evaluate_nodeExpression(%T)", node)) +} + +func (self *_runtime) cmpl_evaluate_nodeArrayLiteral(node *_nodeArrayLiteral) Value { + + valueArray := []Value{} + + for _, node := range node.value { + if node == nil { + valueArray = append(valueArray, emptyValue) + } else { + valueArray = append(valueArray, self.cmpl_evaluate_nodeExpression(node).resolve()) + } + } + + result := self.newArrayOf(valueArray) + + return toValue_object(result) +} + +func (self *_runtime) cmpl_evaluate_nodeAssignExpression(node *_nodeAssignExpression) Value { + + left := self.cmpl_evaluate_nodeExpression(node.left) + right := self.cmpl_evaluate_nodeExpression(node.right) + rightValue := right.resolve() + + result := rightValue + if node.operator != token.ASSIGN { + result = self.calculateBinaryExpression(node.operator, left, rightValue) + } + + self.putValue(left.reference(), result) + + return result +} + +func (self *_runtime) cmpl_evaluate_nodeBinaryExpression(node *_nodeBinaryExpression) Value { + + left := self.cmpl_evaluate_nodeExpression(node.left) + leftValue := left.resolve() + + switch node.operator { + // Logical + case token.LOGICAL_AND: + if !leftValue.bool() { + return leftValue + } + right := self.cmpl_evaluate_nodeExpression(node.right) + return right.resolve() + case token.LOGICAL_OR: + if leftValue.bool() { + return leftValue + } + right := self.cmpl_evaluate_nodeExpression(node.right) + return right.resolve() + } + + return self.calculateBinaryExpression(node.operator, leftValue, self.cmpl_evaluate_nodeExpression(node.right)) +} + +func (self *_runtime) cmpl_evaluate_nodeBinaryExpression_comparison(node *_nodeBinaryExpression) Value { + + 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 := target.resolve() + member := self.cmpl_evaluate_nodeExpression(node.member) + memberValue := member.resolve() + + // TODO Pass in base value as-is, and defer toObject till later? + 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) + + argumentList := []Value{} + if withArgumentList != nil { + argumentList = self.toValueArray(withArgumentList...) + } else { + for _, argumentNode := range node.argumentList { + argumentList = append(argumentList, self.cmpl_evaluate_nodeExpression(argumentNode).resolve()) + } + } + + 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")) + } + } + + 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) + } + + 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 := test.resolve() + if testValue.bool() { + return self.cmpl_evaluate_nodeExpression(node.consequent) + } + return self.cmpl_evaluate_nodeExpression(node.alternate) +} + +func (self *_runtime) cmpl_evaluate_nodeDotExpression(node *_nodeDotExpression) Value { + target := self.cmpl_evaluate_nodeExpression(node.left) + targetValue := target.resolve() + // TODO Pass in base value as-is, and defer toObject till later? + object, err := self.objectCoerce(targetValue) + if err != nil { + panic(self.panicTypeError("Cannot access member '%s' of %s", node.identifier, err.Error())) + } + 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) + + argumentList := []Value{} + for _, argumentNode := range node.argumentList { + argumentList = append(argumentList, self.cmpl_evaluate_nodeExpression(argumentNode).resolve()) + } + + 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")) + } + } + + 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 { + + result := self.newObject() + + for _, property := range node.value { + switch property.kind { + case "value": + result.defineProperty(property.key, self.cmpl_evaluate_nodeExpression(property.value).resolve(), 0111, false) + case "get": + 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.scope.lexical) + descriptor := _property{} + descriptor.mode = 0211 + descriptor.value = _propertyGetSet{nil, setter} + result.defineOwnProperty(property.key, descriptor, false) + default: + panic(fmt.Errorf("Here be dragons: evaluate_nodeObjectLiteral: invalid property.Kind: %v", property.kind)) + } + } + + return toValue_object(result) +} + +func (self *_runtime) cmpl_evaluate_nodeSequenceExpression(node *_nodeSequenceExpression) Value { + var result Value + for _, node := range node.sequence { + result = self.cmpl_evaluate_nodeExpression(node) + result = result.resolve() + } + return result +} + +func (self *_runtime) cmpl_evaluate_nodeUnaryExpression(node *_nodeUnaryExpression) Value { + + target := self.cmpl_evaluate_nodeExpression(node.operand) + switch node.operator { + case token.TYPEOF, token.DELETE: + if target.kind == valueReference && target.reference().invalid() { + if node.operator == token.TYPEOF { + return toValue_string("undefined") + } + return trueValue + } + } + + switch node.operator { + case token.NOT: + targetValue := target.resolve() + if targetValue.bool() { + return falseValue + } + return trueValue + case token.BITWISE_NOT: + targetValue := target.resolve() + integerValue := toInt32(targetValue) + return toValue_int32(^integerValue) + case token.PLUS: + targetValue := target.resolve() + return toValue_float64(targetValue.float64()) + case token.MINUS: + targetValue := target.resolve() + value := targetValue.float64() + // TODO Test this + sign := float64(-1) + if math.Signbit(value) { + sign = 1 + } + return toValue_float64(math.Copysign(value, sign)) + case token.INCREMENT: + targetValue := target.resolve() + if node.postfix { + // Postfix++ + oldValue := targetValue.float64() + newValue := toValue_float64(+1 + oldValue) + self.putValue(target.reference(), newValue) + return toValue_float64(oldValue) + } else { + // ++Prefix + newValue := toValue_float64(+1 + targetValue.float64()) + self.putValue(target.reference(), newValue) + return newValue + } + case token.DECREMENT: + targetValue := target.resolve() + if node.postfix { + // Postfix-- + oldValue := targetValue.float64() + newValue := toValue_float64(-1 + oldValue) + self.putValue(target.reference(), newValue) + return toValue_float64(oldValue) + } else { + // --Prefix + newValue := toValue_float64(-1 + targetValue.float64()) + self.putValue(target.reference(), newValue) + return newValue + } + case token.VOID: + target.resolve() // FIXME Side effect? + return Value{} + case token.DELETE: + reference := target.reference() + if reference == nil { + return trueValue + } + return toValue_bool(target.reference().delete()) + case token.TYPEOF: + targetValue := target.resolve() + switch targetValue.kind { + case valueUndefined: + return toValue_string("undefined") + case valueNull: + return toValue_string("object") + case valueBoolean: + return toValue_string("boolean") + case valueNumber: + return toValue_string("number") + case valueString: + return toValue_string("string") + case valueObject: + if targetValue._object().isCall() { + return toValue_string("function") + } + return toValue_string("object") + default: + // FIXME ? + } + } + + panic(hereBeDragons()) +} + +func (self *_runtime) cmpl_evaluate_nodeVariableExpression(node *_nodeVariableExpression) Value { + if node.initializer != nil { + // FIXME If reference is nil + left := getIdentifierReference(self, self.scope.lexical, node.name, false, _at(node.idx)) + right := self.cmpl_evaluate_nodeExpression(node.initializer) + rightValue := right.resolve() + + self.putValue(left, rightValue) + } + return toValue_string(node.name) +} diff --git a/vendor/github.com/robertkrimen/otto/cmpl_evaluate_statement.go b/vendor/github.com/robertkrimen/otto/cmpl_evaluate_statement.go new file mode 100644 index 0000000..7be1584 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/cmpl_evaluate_statement.go @@ -0,0 +1,421 @@ +package otto + +import ( + "fmt" + "runtime" + + "github.com/robertkrimen/otto/token" +) + +func (self *_runtime) cmpl_evaluate_nodeStatement(node _nodeStatement) Value { + // Allow interpreter interruption + // If the Interrupt channel is nil, then + // we avoid runtime.Gosched() overhead (if any) + // FIXME: Test this + if self.otto.Interrupt != nil { + runtime.Gosched() + select { + case value := <-self.otto.Interrupt: + value() + default: + } + } + + switch node := node.(type) { + + case *_nodeBlockStatement: + 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 + switch node.branch { // FIXME Maybe node.kind? node.operator? + case token.BREAK: + return toValue(newBreakResult(target)) + case token.CONTINUE: + return toValue(newContinueResult(target)) + } + + case *_nodeDebuggerStatement: + return emptyValue // Nothing happens. + + case *_nodeDoWhileStatement: + return self.cmpl_evaluate_nodeDoWhileStatement(node) + + case *_nodeEmptyStatement: + return emptyValue + + case *_nodeExpressionStatement: + return self.cmpl_evaluate_nodeExpression(node.expression) + + case *_nodeForInStatement: + return self.cmpl_evaluate_nodeForInStatement(node) + + case *_nodeForStatement: + return self.cmpl_evaluate_nodeForStatement(node) + + case *_nodeIfStatement: + return self.cmpl_evaluate_nodeIfStatement(node) + + case *_nodeLabelledStatement: + self.labels = append(self.labels, node.label) + defer func() { + if len(self.labels) > 0 { + self.labels = self.labels[:len(self.labels)-1] // Pop the label + } else { + self.labels = nil + } + }() + return self.cmpl_evaluate_nodeStatement(node.statement) + + case *_nodeReturnStatement: + if node.argument != nil { + return toValue(newReturnResult(self.cmpl_evaluate_nodeExpression(node.argument).resolve())) + } + return toValue(newReturnResult(Value{})) + + case *_nodeSwitchStatement: + return self.cmpl_evaluate_nodeSwitchStatement(node) + + case *_nodeThrowStatement: + value := self.cmpl_evaluate_nodeExpression(node.argument).resolve() + panic(newException(value)) + + case *_nodeTryStatement: + return self.cmpl_evaluate_nodeTryStatement(node) + + case *_nodeVariableStatement: + // Variables are already defined, this is initialization only + for _, variable := range node.list { + self.cmpl_evaluate_nodeVariableExpression(variable.(*_nodeVariableExpression)) + } + return emptyValue + + case *_nodeWhileStatement: + return self.cmpl_evaluate_nodeWhileStatement(node) + + case *_nodeWithStatement: + return self.cmpl_evaluate_nodeWithStatement(node) + + } + + panic(fmt.Errorf("Here be dragons: evaluate_nodeStatement(%T)", node)) +} + +func (self *_runtime) cmpl_evaluate_nodeStatementList(list []_nodeStatement) Value { + var result Value + for _, node := range list { + value := self.cmpl_evaluate_nodeStatement(node) + switch value.kind { + case valueResult: + return value + case valueEmpty: + default: + // 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 = value.resolve() + } + } + return result +} + +func (self *_runtime) cmpl_evaluate_nodeDoWhileStatement(node *_nodeDoWhileStatement) Value { + + labels := append(self.labels, "") + self.labels = nil + + test := node.test + + result := emptyValue +resultBreak: + for { + for _, node := range node.body { + value := self.cmpl_evaluate_nodeStatement(node) + switch value.kind { + case valueResult: + switch value.evaluateBreakContinue(labels) { + case resultReturn: + return value + case resultBreak: + break resultBreak + case resultContinue: + goto resultContinue + } + case valueEmpty: + default: + result = value + } + } + resultContinue: + if !self.cmpl_evaluate_nodeExpression(test).resolve().bool() { + // Stahp: do ... while (false) + break + } + } + return result +} + +func (self *_runtime) cmpl_evaluate_nodeForInStatement(node *_nodeForInStatement) Value { + + labels := append(self.labels, "") + self.labels = nil + + source := self.cmpl_evaluate_nodeExpression(node.source) + sourceValue := source.resolve() + + switch sourceValue.kind { + case valueUndefined, valueNull: + return emptyValue + } + + sourceObject := self.toObject(sourceValue) + + into := node.into + body := node.body + + result := emptyValue + object := sourceObject + for object != nil { + 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 := into.string() + // TODO Should be true or false (strictness) depending on context + into = toValue(getIdentifierReference(self, self.scope.lexical, identifier, false, -1)) + } + self.putValue(into.reference(), toValue_string(name)) + for _, node := range body { + value := self.cmpl_evaluate_nodeStatement(node) + switch value.kind { + case valueResult: + switch value.evaluateBreakContinue(labels) { + case resultReturn: + enumerateValue = value + return false + case resultBreak: + object = nil + return false + case resultContinue: + return true + } + case valueEmpty: + default: + enumerateValue = value + } + } + return true + }) + if object == nil { + break + } + object = object.prototype + if !enumerateValue.isEmpty() { + result = enumerateValue + } + } + return result +} + +func (self *_runtime) cmpl_evaluate_nodeForStatement(node *_nodeForStatement) Value { + + labels := append(self.labels, "") + self.labels = nil + + initializer := node.initializer + test := node.test + update := node.update + body := node.body + + if initializer != nil { + initialResult := self.cmpl_evaluate_nodeExpression(initializer) + initialResult.resolve() // Side-effect trigger + } + + result := emptyValue +resultBreak: + for { + if test != nil { + testResult := self.cmpl_evaluate_nodeExpression(test) + testResultValue := testResult.resolve() + if testResultValue.bool() == false { + break + } + } + for _, node := range body { + value := self.cmpl_evaluate_nodeStatement(node) + switch value.kind { + case valueResult: + switch value.evaluateBreakContinue(labels) { + case resultReturn: + return value + case resultBreak: + break resultBreak + case resultContinue: + goto resultContinue + } + case valueEmpty: + default: + result = value + } + } + resultContinue: + if update != nil { + updateResult := self.cmpl_evaluate_nodeExpression(update) + updateResult.resolve() // Side-effect trigger + } + } + return result +} + +func (self *_runtime) cmpl_evaluate_nodeIfStatement(node *_nodeIfStatement) Value { + test := self.cmpl_evaluate_nodeExpression(node.test) + 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 emptyValue +} + +func (self *_runtime) cmpl_evaluate_nodeSwitchStatement(node *_nodeSwitchStatement) Value { + + labels := append(self.labels, "") + self.labels = nil + + discriminantResult := self.cmpl_evaluate_nodeExpression(node.discriminant) + target := node.default_ + + for index, clause := range node.body { + test := clause.test + if test != nil { + if self.calculateComparison(token.STRICT_EQUAL, discriminantResult, self.cmpl_evaluate_nodeExpression(test)) { + target = index + break + } + } + } + + result := emptyValue + if target != -1 { + for _, clause := range node.body[target:] { + for _, statement := range clause.consequent { + value := self.cmpl_evaluate_nodeStatement(statement) + switch value.kind { + case valueResult: + switch value.evaluateBreak(labels) { + case resultReturn: + return value + case resultBreak: + return emptyValue + } + case valueEmpty: + default: + result = value + } + } + } + } + + return result +} + +func (self *_runtime) cmpl_evaluate_nodeTryStatement(node *_nodeTryStatement) Value { + tryCatchValue, exception := self.tryCatchEvaluate(func() Value { + return self.cmpl_evaluate_nodeStatement(node.body) + }) + + if exception && node.catch != nil { + outer := self.scope.lexical + self.scope.lexical = self.newDeclarationStash(outer) + defer func() { + self.scope.lexical = outer + }() + // TODO If necessary, convert TypeError => TypeError + // That, is, such errors can be thrown despite not being JavaScript "native" + // strict = false + self.scope.lexical.setValue(node.catch.parameter, tryCatchValue, false) + + // FIXME node.CatchParameter + // FIXME node.Catch + tryCatchValue, exception = self.tryCatchEvaluate(func() Value { + return self.cmpl_evaluate_nodeStatement(node.catch.body) + }) + } + + if node.finally != nil { + finallyValue := self.cmpl_evaluate_nodeStatement(node.finally) + if finallyValue.kind == valueResult { + return finallyValue + } + } + + if exception { + panic(newException(tryCatchValue)) + } + + return tryCatchValue +} + +func (self *_runtime) cmpl_evaluate_nodeWhileStatement(node *_nodeWhileStatement) Value { + + test := node.test + body := node.body + labels := append(self.labels, "") + self.labels = nil + + result := emptyValue +resultBreakContinue: + for { + if !self.cmpl_evaluate_nodeExpression(test).resolve().bool() { + // Stahp: while (false) ... + break + } + for _, node := range body { + value := self.cmpl_evaluate_nodeStatement(node) + switch value.kind { + case valueResult: + switch value.evaluateBreakContinue(labels) { + case resultReturn: + return value + case resultBreak: + break resultBreakContinue + case resultContinue: + continue resultBreakContinue + } + case valueEmpty: + default: + result = value + } + } + } + return result +} + +func (self *_runtime) cmpl_evaluate_nodeWithStatement(node *_nodeWithStatement) Value { + object := self.cmpl_evaluate_nodeExpression(node.object) + outer := self.scope.lexical + lexical := self.newObjectStash(self.toObject(object.resolve()), outer) + self.scope.lexical = lexical + defer func() { + self.scope.lexical = outer + }() + + return self.cmpl_evaluate_nodeStatement(node.body) +} diff --git a/vendor/github.com/robertkrimen/otto/cmpl_parse.go b/vendor/github.com/robertkrimen/otto/cmpl_parse.go new file mode 100644 index 0000000..e758a52 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/cmpl_parse.go @@ -0,0 +1,650 @@ +package otto + +import ( + "fmt" + "regexp" + + "github.com/robertkrimen/otto/ast" + "github.com/robertkrimen/otto/file" + "github.com/robertkrimen/otto/token" +) + +var trueLiteral = &_nodeLiteral{value: toValue_bool(true)} +var falseLiteral = &_nodeLiteral{value: toValue_bool(false)} +var nullLiteral = &_nodeLiteral{value: nullValue} +var emptyStatement = &_nodeEmptyStatement{} + +func (cmpl *_compiler) parseExpression(in ast.Expression) _nodeExpression { + if in == nil { + return nil + } + + switch in := in.(type) { + + case *ast.ArrayLiteral: + out := &_nodeArrayLiteral{ + value: make([]_nodeExpression, len(in.Value)), + } + for i, value := range in.Value { + out.value[i] = cmpl.parseExpression(value) + } + return out + + case *ast.AssignExpression: + return &_nodeAssignExpression{ + operator: in.Operator, + left: cmpl.parseExpression(in.Left), + right: cmpl.parseExpression(in.Right), + } + + case *ast.BinaryExpression: + return &_nodeBinaryExpression{ + operator: in.Operator, + left: cmpl.parseExpression(in.Left), + right: cmpl.parseExpression(in.Right), + comparison: in.Comparison, + } + + case *ast.BooleanLiteral: + if in.Value { + return trueLiteral + } + return falseLiteral + + case *ast.BracketExpression: + return &_nodeBracketExpression{ + idx: in.Left.Idx0(), + left: cmpl.parseExpression(in.Left), + member: cmpl.parseExpression(in.Member), + } + + case *ast.CallExpression: + out := &_nodeCallExpression{ + callee: cmpl.parseExpression(in.Callee), + argumentList: make([]_nodeExpression, len(in.ArgumentList)), + } + for i, value := range in.ArgumentList { + out.argumentList[i] = cmpl.parseExpression(value) + } + return out + + case *ast.ConditionalExpression: + return &_nodeConditionalExpression{ + test: cmpl.parseExpression(in.Test), + consequent: cmpl.parseExpression(in.Consequent), + alternate: cmpl.parseExpression(in.Alternate), + } + + case *ast.DotExpression: + return &_nodeDotExpression{ + idx: in.Left.Idx0(), + left: cmpl.parseExpression(in.Left), + identifier: in.Identifier.Name, + } + + case *ast.FunctionLiteral: + name := "" + if in.Name != nil { + name = in.Name.Name + } + out := &_nodeFunctionLiteral{ + name: name, + body: cmpl.parseStatement(in.Body), + source: in.Source, + file: cmpl.file, + } + if in.ParameterList != nil { + list := in.ParameterList.List + out.parameterList = make([]string, len(list)) + for i, value := range list { + out.parameterList[i] = value.Name + } + } + for _, value := range in.DeclarationList { + switch value := value.(type) { + case *ast.FunctionDeclaration: + out.functionList = append(out.functionList, cmpl.parseExpression(value.Function).(*_nodeFunctionLiteral)) + case *ast.VariableDeclaration: + for _, value := range value.List { + out.varList = append(out.varList, value.Name) + } + default: + panic(fmt.Errorf("Here be dragons: parseProgram.declaration(%T)", value)) + } + } + return out + + case *ast.Identifier: + return &_nodeIdentifier{ + idx: in.Idx, + name: in.Name, + } + + case *ast.NewExpression: + out := &_nodeNewExpression{ + callee: cmpl.parseExpression(in.Callee), + argumentList: make([]_nodeExpression, len(in.ArgumentList)), + } + for i, value := range in.ArgumentList { + out.argumentList[i] = cmpl.parseExpression(value) + } + return out + + case *ast.NullLiteral: + return nullLiteral + + case *ast.NumberLiteral: + return &_nodeLiteral{ + value: toValue(in.Value), + } + + case *ast.ObjectLiteral: + out := &_nodeObjectLiteral{ + value: make([]_nodeProperty, len(in.Value)), + } + for i, value := range in.Value { + out.value[i] = _nodeProperty{ + key: value.Key, + kind: value.Kind, + value: cmpl.parseExpression(value.Value), + } + } + return out + + case *ast.RegExpLiteral: + return &_nodeRegExpLiteral{ + flags: in.Flags, + pattern: in.Pattern, + } + + case *ast.SequenceExpression: + out := &_nodeSequenceExpression{ + sequence: make([]_nodeExpression, len(in.Sequence)), + } + for i, value := range in.Sequence { + out.sequence[i] = cmpl.parseExpression(value) + } + return out + + case *ast.StringLiteral: + return &_nodeLiteral{ + value: toValue_string(in.Value), + } + + case *ast.ThisExpression: + return &_nodeThisExpression{} + + case *ast.UnaryExpression: + return &_nodeUnaryExpression{ + operator: in.Operator, + operand: cmpl.parseExpression(in.Operand), + postfix: in.Postfix, + } + + case *ast.VariableExpression: + return &_nodeVariableExpression{ + idx: in.Idx0(), + name: in.Name, + initializer: cmpl.parseExpression(in.Initializer), + } + + } + + panic(fmt.Errorf("Here be dragons: cmpl.parseExpression(%T)", in)) +} + +func (cmpl *_compiler) parseStatement(in ast.Statement) _nodeStatement { + if in == nil { + return nil + } + + switch in := in.(type) { + + case *ast.BlockStatement: + out := &_nodeBlockStatement{ + list: make([]_nodeStatement, len(in.List)), + } + for i, value := range in.List { + out.list[i] = cmpl.parseStatement(value) + } + return out + + case *ast.BranchStatement: + out := &_nodeBranchStatement{ + branch: in.Token, + } + if in.Label != nil { + out.label = in.Label.Name + } + return out + + case *ast.DebuggerStatement: + return &_nodeDebuggerStatement{} + + case *ast.DoWhileStatement: + out := &_nodeDoWhileStatement{ + test: cmpl.parseExpression(in.Test), + } + body := cmpl.parseStatement(in.Body) + if block, ok := body.(*_nodeBlockStatement); ok { + out.body = block.list + } else { + out.body = append(out.body, body) + } + return out + + case *ast.EmptyStatement: + return emptyStatement + + case *ast.ExpressionStatement: + return &_nodeExpressionStatement{ + expression: cmpl.parseExpression(in.Expression), + } + + case *ast.ForInStatement: + out := &_nodeForInStatement{ + into: cmpl.parseExpression(in.Into), + source: cmpl.parseExpression(in.Source), + } + body := cmpl.parseStatement(in.Body) + if block, ok := body.(*_nodeBlockStatement); ok { + out.body = block.list + } else { + out.body = append(out.body, body) + } + return out + + case *ast.ForStatement: + out := &_nodeForStatement{ + initializer: cmpl.parseExpression(in.Initializer), + update: cmpl.parseExpression(in.Update), + test: cmpl.parseExpression(in.Test), + } + body := cmpl.parseStatement(in.Body) + if block, ok := body.(*_nodeBlockStatement); ok { + out.body = block.list + } else { + out.body = append(out.body, body) + } + return out + + case *ast.IfStatement: + return &_nodeIfStatement{ + test: cmpl.parseExpression(in.Test), + consequent: cmpl.parseStatement(in.Consequent), + alternate: cmpl.parseStatement(in.Alternate), + } + + case *ast.LabelledStatement: + return &_nodeLabelledStatement{ + label: in.Label.Name, + statement: cmpl.parseStatement(in.Statement), + } + + case *ast.ReturnStatement: + return &_nodeReturnStatement{ + argument: cmpl.parseExpression(in.Argument), + } + + case *ast.SwitchStatement: + out := &_nodeSwitchStatement{ + discriminant: cmpl.parseExpression(in.Discriminant), + default_: in.Default, + body: make([]*_nodeCaseStatement, len(in.Body)), + } + for i, clause := range in.Body { + out.body[i] = &_nodeCaseStatement{ + test: cmpl.parseExpression(clause.Test), + consequent: make([]_nodeStatement, len(clause.Consequent)), + } + for j, value := range clause.Consequent { + out.body[i].consequent[j] = cmpl.parseStatement(value) + } + } + return out + + case *ast.ThrowStatement: + return &_nodeThrowStatement{ + argument: cmpl.parseExpression(in.Argument), + } + + case *ast.TryStatement: + out := &_nodeTryStatement{ + body: cmpl.parseStatement(in.Body), + finally: cmpl.parseStatement(in.Finally), + } + if in.Catch != nil { + out.catch = &_nodeCatchStatement{ + parameter: in.Catch.Parameter.Name, + body: cmpl.parseStatement(in.Catch.Body), + } + } + return out + + case *ast.VariableStatement: + out := &_nodeVariableStatement{ + list: make([]_nodeExpression, len(in.List)), + } + for i, value := range in.List { + out.list[i] = cmpl.parseExpression(value) + } + return out + + case *ast.WhileStatement: + out := &_nodeWhileStatement{ + test: cmpl.parseExpression(in.Test), + } + body := cmpl.parseStatement(in.Body) + if block, ok := body.(*_nodeBlockStatement); ok { + out.body = block.list + } else { + out.body = append(out.body, body) + } + return out + + case *ast.WithStatement: + return &_nodeWithStatement{ + object: cmpl.parseExpression(in.Object), + body: cmpl.parseStatement(in.Body), + } + + } + + panic(fmt.Errorf("Here be dragons: cmpl.parseStatement(%T)", in)) +} + +func cmpl_parse(in *ast.Program) *_nodeProgram { + cmpl := _compiler{ + program: in, + } + return cmpl.parse() +} + +func (cmpl *_compiler) _parse(in *ast.Program) *_nodeProgram { + out := &_nodeProgram{ + body: make([]_nodeStatement, len(in.Body)), + file: in.File, + } + for i, value := range in.Body { + out.body[i] = cmpl.parseStatement(value) + } + for _, value := range in.DeclarationList { + switch value := value.(type) { + case *ast.FunctionDeclaration: + out.functionList = append(out.functionList, cmpl.parseExpression(value.Function).(*_nodeFunctionLiteral)) + case *ast.VariableDeclaration: + for _, value := range value.List { + out.varList = append(out.varList, value.Name) + } + default: + panic(fmt.Errorf("Here be dragons: cmpl.parseProgram.DeclarationList(%T)", value)) + } + } + return out +} + +type _nodeProgram struct { + body []_nodeStatement + + varList []string + functionList []*_nodeFunctionLiteral + + variableList []_nodeDeclaration + + file *file.File +} + +type _nodeDeclaration struct { + name string + definition _node +} + +type _node interface { +} + +type ( + _nodeExpression interface { + _node + _expressionNode() + } + + _nodeArrayLiteral struct { + value []_nodeExpression + } + + _nodeAssignExpression struct { + operator token.Token + left _nodeExpression + right _nodeExpression + } + + _nodeBinaryExpression struct { + operator token.Token + left _nodeExpression + right _nodeExpression + comparison bool + } + + _nodeBracketExpression struct { + idx file.Idx + left _nodeExpression + member _nodeExpression + } + + _nodeCallExpression struct { + callee _nodeExpression + argumentList []_nodeExpression + } + + _nodeConditionalExpression struct { + test _nodeExpression + consequent _nodeExpression + alternate _nodeExpression + } + + _nodeDotExpression struct { + idx file.Idx + left _nodeExpression + identifier string + } + + _nodeFunctionLiteral struct { + name string + body _nodeStatement + source string + parameterList []string + varList []string + functionList []*_nodeFunctionLiteral + file *file.File + } + + _nodeIdentifier struct { + idx file.Idx + name string + } + + _nodeLiteral struct { + value Value + } + + _nodeNewExpression struct { + callee _nodeExpression + argumentList []_nodeExpression + } + + _nodeObjectLiteral struct { + value []_nodeProperty + } + + _nodeProperty struct { + key string + kind string + value _nodeExpression + } + + _nodeRegExpLiteral struct { + flags string + pattern string // Value? + regexp *regexp.Regexp + } + + _nodeSequenceExpression struct { + sequence []_nodeExpression + } + + _nodeThisExpression struct { + } + + _nodeUnaryExpression struct { + operator token.Token + operand _nodeExpression + postfix bool + } + + _nodeVariableExpression struct { + idx file.Idx + name string + initializer _nodeExpression + } +) + +type ( + _nodeStatement interface { + _node + _statementNode() + } + + _nodeBlockStatement struct { + list []_nodeStatement + } + + _nodeBranchStatement struct { + branch token.Token + label string + } + + _nodeCaseStatement struct { + test _nodeExpression + consequent []_nodeStatement + } + + _nodeCatchStatement struct { + parameter string + body _nodeStatement + } + + _nodeDebuggerStatement struct { + } + + _nodeDoWhileStatement struct { + test _nodeExpression + body []_nodeStatement + } + + _nodeEmptyStatement struct { + } + + _nodeExpressionStatement struct { + expression _nodeExpression + } + + _nodeForInStatement struct { + into _nodeExpression + source _nodeExpression + body []_nodeStatement + } + + _nodeForStatement struct { + initializer _nodeExpression + update _nodeExpression + test _nodeExpression + body []_nodeStatement + } + + _nodeIfStatement struct { + test _nodeExpression + consequent _nodeStatement + alternate _nodeStatement + } + + _nodeLabelledStatement struct { + label string + statement _nodeStatement + } + + _nodeReturnStatement struct { + argument _nodeExpression + } + + _nodeSwitchStatement struct { + discriminant _nodeExpression + default_ int + body []*_nodeCaseStatement + } + + _nodeThrowStatement struct { + argument _nodeExpression + } + + _nodeTryStatement struct { + body _nodeStatement + catch *_nodeCatchStatement + finally _nodeStatement + } + + _nodeVariableStatement struct { + list []_nodeExpression + } + + _nodeWhileStatement struct { + test _nodeExpression + body []_nodeStatement + } + + _nodeWithStatement struct { + object _nodeExpression + body _nodeStatement + } +) + +// _expressionNode + +func (*_nodeArrayLiteral) _expressionNode() {} +func (*_nodeAssignExpression) _expressionNode() {} +func (*_nodeBinaryExpression) _expressionNode() {} +func (*_nodeBracketExpression) _expressionNode() {} +func (*_nodeCallExpression) _expressionNode() {} +func (*_nodeConditionalExpression) _expressionNode() {} +func (*_nodeDotExpression) _expressionNode() {} +func (*_nodeFunctionLiteral) _expressionNode() {} +func (*_nodeIdentifier) _expressionNode() {} +func (*_nodeLiteral) _expressionNode() {} +func (*_nodeNewExpression) _expressionNode() {} +func (*_nodeObjectLiteral) _expressionNode() {} +func (*_nodeRegExpLiteral) _expressionNode() {} +func (*_nodeSequenceExpression) _expressionNode() {} +func (*_nodeThisExpression) _expressionNode() {} +func (*_nodeUnaryExpression) _expressionNode() {} +func (*_nodeVariableExpression) _expressionNode() {} + +// _statementNode + +func (*_nodeBlockStatement) _statementNode() {} +func (*_nodeBranchStatement) _statementNode() {} +func (*_nodeCaseStatement) _statementNode() {} +func (*_nodeCatchStatement) _statementNode() {} +func (*_nodeDebuggerStatement) _statementNode() {} +func (*_nodeDoWhileStatement) _statementNode() {} +func (*_nodeEmptyStatement) _statementNode() {} +func (*_nodeExpressionStatement) _statementNode() {} +func (*_nodeForInStatement) _statementNode() {} +func (*_nodeForStatement) _statementNode() {} +func (*_nodeIfStatement) _statementNode() {} +func (*_nodeLabelledStatement) _statementNode() {} +func (*_nodeReturnStatement) _statementNode() {} +func (*_nodeSwitchStatement) _statementNode() {} +func (*_nodeThrowStatement) _statementNode() {} +func (*_nodeTryStatement) _statementNode() {} +func (*_nodeVariableStatement) _statementNode() {} +func (*_nodeWhileStatement) _statementNode() {} +func (*_nodeWithStatement) _statementNode() {} diff --git a/vendor/github.com/robertkrimen/otto/console.go b/vendor/github.com/robertkrimen/otto/console.go new file mode 100644 index 0000000..948face --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/console.go @@ -0,0 +1,51 @@ +package otto + +import ( + "fmt" + "os" + "strings" +) + +func formatForConsole(argumentList []Value) string { + output := []string{} + for _, argument := range argumentList { + output = append(output, fmt.Sprintf("%v", argument)) + } + return strings.Join(output, " ") +} + +func builtinConsole_log(call FunctionCall) Value { + fmt.Fprintln(os.Stdout, formatForConsole(call.ArgumentList)) + return Value{} +} + +func builtinConsole_error(call FunctionCall) Value { + fmt.Fprintln(os.Stdout, formatForConsole(call.ArgumentList)) + return Value{} +} + +// Nothing happens. +func builtinConsole_dir(call FunctionCall) Value { + return Value{} +} + +func builtinConsole_time(call FunctionCall) Value { + return Value{} +} + +func builtinConsole_timeEnd(call FunctionCall) Value { + return Value{} +} + +func builtinConsole_trace(call FunctionCall) Value { + return Value{} +} + +func builtinConsole_assert(call FunctionCall) Value { + return Value{} +} + +func (runtime *_runtime) newConsole() *_object { + + return newConsoleObject(runtime) +} diff --git a/vendor/github.com/robertkrimen/otto/dbg.go b/vendor/github.com/robertkrimen/otto/dbg.go new file mode 100644 index 0000000..51fbdc2 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/dbg.go @@ -0,0 +1,9 @@ +// This file was AUTOMATICALLY GENERATED by dbg-import (smuggol) for github.com/robertkrimen/dbg + +package otto + +import ( + Dbg "github.com/robertkrimen/otto/dbg" +) + +var dbg, dbgf = Dbg.New() diff --git a/vendor/github.com/robertkrimen/otto/dbg/dbg.go b/vendor/github.com/robertkrimen/otto/dbg/dbg.go new file mode 100644 index 0000000..83bf6c5 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/dbg/dbg.go @@ -0,0 +1,387 @@ +// 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...) + } + } +} diff --git a/vendor/github.com/robertkrimen/otto/error.go b/vendor/github.com/robertkrimen/otto/error.go new file mode 100644 index 0000000..1114710 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/error.go @@ -0,0 +1,245 @@ +package otto + +import ( + "errors" + "fmt" + "strings" + + "github.com/robertkrimen/otto/file" +) + +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 + trace []_frame + + offset int +} + +type _frame struct { + file *file.File + offset int + callee string +} + +var ( + nativeFrame = _frame{} +) + +type _at int + +func (fr _frame) location() string { + if fr.file == nil { + return "" + } + path := fr.file.Name() + line, column := _position(fr.file, fr.offset) + + if path == "" { + path = "" + } + + str := fmt.Sprintf("%s:%d:%d", path, line, column) + + if fr.callee != "" { + str = fmt.Sprintf("%s (%s)", fr.callee, str) + } + + return str +} + +func _position(file *file.File, offset int) (line, column int) { + { + offset := offset - file.Base() + if offset < 0 { + return -offset, -1 + } + + src := file.Source() + if offset >= len(src) { + return -offset, -len(src) + } + src = src[:offset] + + line := 1 + strings.Count(src, "\n") + column := 0 + if index := strings.LastIndex(src, "\n"); index >= 0 { + column = offset - index + } else { + column = 1 + len(src) + } + return line, column + } +} + +// An Error represents a runtime error, e.g. a TypeError, a ReferenceError, etc. +type Error struct { + _error +} + +// Error returns a description of the error +// +// TypeError: 'def' is not a function +// +func (err Error) Error() string { + if len(err.name) == 0 { + return err.message + } + if len(err.message) == 0 { + return err.name + } + return fmt.Sprintf("%s: %s", err.name, err.message) +} + +// String returns a description of the error and a trace of where the +// error occurred. +// +// TypeError: 'def' is not a function +// at xyz (:3:9) +// at :7:1/ +// +func (err Error) String() string { + str := err.Error() + "\n" + for _, frame := range err.trace { + str += " at " + frame.location() + "\n" + } + return str +} + +func (err _error) describe(format string, in ...interface{}) string { + return fmt.Sprintf(format, in...) +} + +func (self _error) messageValue() Value { + if self.message == "" { + return Value{} + } + return toValue_string(self.message) +} + +func (rt *_runtime) typeErrorResult(throw bool) bool { + if throw { + panic(rt.panicTypeError()) + } + return false +} + +func newError(rt *_runtime, name string, in ...interface{}) _error { + err := _error{ + name: name, + offset: -1, + } + description := "" + length := len(in) + + if rt != nil { + scope := rt.scope + frame := scope.frame + if length > 0 { + if at, ok := in[length-1].(_at); ok { + in = in[0 : length-1] + if scope != nil { + frame.offset = int(at) + } + length -= 1 + } + if length > 0 { + description, in = in[0].(string), in[1:] + } + } + limit := 10 + err.trace = append(err.trace, frame) + if scope != nil { + for limit > 0 { + scope = scope.outer + if scope == nil { + break + } + if scope.frame.offset >= 0 { + err.trace = append(err.trace, scope.frame) + } + limit-- + } + } + } else { + if length > 0 { + description, in = in[0].(string), in[1:] + } + } + err.message = err.describe(description, in...) + return err +} + +func (rt *_runtime) panicTypeError(argumentList ...interface{}) *_exception { + return &_exception{ + value: newError(rt, "TypeError", argumentList...), + } +} + +func (rt *_runtime) panicReferenceError(argumentList ...interface{}) *_exception { + return &_exception{ + value: newError(rt, "ReferenceError", argumentList...), + } +} + +func (rt *_runtime) panicURIError(argumentList ...interface{}) *_exception { + return &_exception{ + value: newError(rt, "URIError", argumentList...), + } +} + +func (rt *_runtime) panicSyntaxError(argumentList ...interface{}) *_exception { + return &_exception{ + value: newError(rt, "SyntaxError", argumentList...), + } +} + +func (rt *_runtime) panicRangeError(argumentList ...interface{}) *_exception { + return &_exception{ + value: newError(rt, "RangeError", argumentList...), + } +} + +func catchPanic(function func()) (err error) { + defer func() { + if caught := recover(); caught != nil { + if exception, ok := caught.(*_exception); ok { + caught = exception.eject() + } + switch caught := caught.(type) { + case _error: + err = &Error{caught} + return + case Value: + if vl := caught._object(); vl != nil { + switch vl := vl.value.(type) { + case _error: + err = &Error{vl} + return + } + } + err = errors.New(caught.string()) + return + } + panic(caught) + } + }() + function() + return nil +} diff --git a/vendor/github.com/robertkrimen/otto/evaluate.go b/vendor/github.com/robertkrimen/otto/evaluate.go new file mode 100644 index 0000000..093054c --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/evaluate.go @@ -0,0 +1,318 @@ +package otto + +import ( + "fmt" + "math" + "strings" + + "github.com/robertkrimen/otto/token" +) + +func (self *_runtime) evaluateMultiply(left float64, right float64) Value { + // TODO 11.5.1 + return Value{} +} + +func (self *_runtime) evaluateDivide(left float64, right float64) Value { + if math.IsNaN(left) || math.IsNaN(right) { + return NaNValue() + } + if math.IsInf(left, 0) && math.IsInf(right, 0) { + return NaNValue() + } + if left == 0 && right == 0 { + return NaNValue() + } + if math.IsInf(left, 0) { + if math.Signbit(left) == math.Signbit(right) { + return positiveInfinityValue() + } else { + return negativeInfinityValue() + } + } + if math.IsInf(right, 0) { + if math.Signbit(left) == math.Signbit(right) { + return positiveZeroValue() + } else { + return negativeZeroValue() + } + } + if right == 0 { + if math.Signbit(left) == math.Signbit(right) { + return positiveInfinityValue() + } else { + return negativeInfinityValue() + } + } + return toValue_float64(left / right) +} + +func (self *_runtime) evaluateModulo(left float64, right float64) Value { + // TODO 11.5.3 + return Value{} +} + +func (self *_runtime) calculateBinaryExpression(operator token.Token, left Value, right Value) Value { + + leftValue := left.resolve() + + switch operator { + + // Additive + case token.PLUS: + leftValue = toPrimitive(leftValue) + rightValue := right.resolve() + rightValue = toPrimitive(rightValue) + + if leftValue.IsString() || rightValue.IsString() { + return toValue_string(strings.Join([]string{leftValue.string(), rightValue.string()}, "")) + } else { + return toValue_float64(leftValue.float64() + rightValue.float64()) + } + case token.MINUS: + rightValue := right.resolve() + return toValue_float64(leftValue.float64() - rightValue.float64()) + + // Multiplicative + case token.MULTIPLY: + rightValue := right.resolve() + return toValue_float64(leftValue.float64() * rightValue.float64()) + case token.SLASH: + rightValue := right.resolve() + return self.evaluateDivide(leftValue.float64(), rightValue.float64()) + case token.REMAINDER: + rightValue := right.resolve() + return toValue_float64(math.Mod(leftValue.float64(), rightValue.float64())) + + // Logical + case token.LOGICAL_AND: + left := leftValue.bool() + if !left { + return falseValue + } + return toValue_bool(right.resolve().bool()) + case token.LOGICAL_OR: + left := leftValue.bool() + if left { + return trueValue + } + return toValue_bool(right.resolve().bool()) + + // Bitwise + case token.AND: + rightValue := right.resolve() + return toValue_int32(toInt32(leftValue) & toInt32(rightValue)) + case token.OR: + rightValue := right.resolve() + return toValue_int32(toInt32(leftValue) | toInt32(rightValue)) + case token.EXCLUSIVE_OR: + rightValue := right.resolve() + return toValue_int32(toInt32(leftValue) ^ toInt32(rightValue)) + + // Shift + // (Masking of 0x1f is to restrict the shift to a maximum of 31 places) + case token.SHIFT_LEFT: + rightValue := right.resolve() + return toValue_int32(toInt32(leftValue) << (toUint32(rightValue) & 0x1f)) + case token.SHIFT_RIGHT: + rightValue := right.resolve() + return toValue_int32(toInt32(leftValue) >> (toUint32(rightValue) & 0x1f)) + case token.UNSIGNED_SHIFT_RIGHT: + rightValue := right.resolve() + // Shifting an unsigned integer is a logical shift + return toValue_uint32(toUint32(leftValue) >> (toUint32(rightValue) & 0x1f)) + + case token.INSTANCEOF: + rightValue := right.resolve() + if !rightValue.IsObject() { + panic(self.panicTypeError("Expecting a function in instanceof check, but got: %v", rightValue)) + } + return toValue_bool(rightValue._object().hasInstance(leftValue)) + + case token.IN: + rightValue := right.resolve() + if !rightValue.IsObject() { + panic(self.panicTypeError()) + } + return toValue_bool(rightValue._object().hasProperty(leftValue.string())) + } + + panic(hereBeDragons(operator)) +} + +func valueKindDispatchKey(left _valueKind, right _valueKind) int { + return (int(left) << 2) + int(right) +} + +var equalDispatch map[int](func(Value, Value) bool) = makeEqualDispatch() + +func makeEqualDispatch() map[int](func(Value, Value) bool) { + key := valueKindDispatchKey + return map[int](func(Value, Value) bool){ + + key(valueNumber, valueObject): func(x Value, y Value) bool { return x.float64() == y.float64() }, + key(valueString, valueObject): func(x Value, y Value) bool { return x.float64() == y.float64() }, + key(valueObject, valueNumber): func(x Value, y Value) bool { return x.float64() == y.float64() }, + key(valueObject, valueString): func(x Value, y Value) bool { return x.float64() == y.float64() }, + } +} + +type _lessThanResult int + +const ( + lessThanFalse _lessThanResult = iota + lessThanTrue + lessThanUndefined +) + +func calculateLessThan(left Value, right Value, leftFirst bool) _lessThanResult { + + x := Value{} + y := x + + if leftFirst { + x = toNumberPrimitive(left) + y = toNumberPrimitive(right) + } else { + y = toNumberPrimitive(right) + x = toNumberPrimitive(left) + } + + result := false + if x.kind != valueString || y.kind != valueString { + x, y := x.float64(), y.float64() + if math.IsNaN(x) || math.IsNaN(y) { + return lessThanUndefined + } + result = x < y + } else { + x, y := x.string(), y.string() + result = x < y + } + + if result { + return lessThanTrue + } + + return lessThanFalse +} + +// FIXME Probably a map is not the most efficient way to do this +var lessThanTable [4](map[_lessThanResult]bool) = [4](map[_lessThanResult]bool){ + // < + map[_lessThanResult]bool{ + lessThanFalse: false, + lessThanTrue: true, + lessThanUndefined: false, + }, + + // > + map[_lessThanResult]bool{ + lessThanFalse: false, + lessThanTrue: true, + lessThanUndefined: false, + }, + + // <= + map[_lessThanResult]bool{ + lessThanFalse: true, + lessThanTrue: false, + lessThanUndefined: false, + }, + + // >= + map[_lessThanResult]bool{ + lessThanFalse: true, + lessThanTrue: false, + lessThanUndefined: false, + }, +} + +func (self *_runtime) calculateComparison(comparator token.Token, left Value, right Value) bool { + + // FIXME Use strictEqualityComparison? + // TODO This might be redundant now (with regards to evaluateComparison) + x := left.resolve() + y := right.resolve() + + kindEqualKind := false + result := true + negate := false + + switch comparator { + case token.LESS: + result = lessThanTable[0][calculateLessThan(x, y, true)] + case token.GREATER: + result = lessThanTable[1][calculateLessThan(y, x, false)] + case token.LESS_OR_EQUAL: + result = lessThanTable[2][calculateLessThan(y, x, false)] + case token.GREATER_OR_EQUAL: + result = lessThanTable[3][calculateLessThan(x, y, true)] + case token.STRICT_NOT_EQUAL: + negate = true + fallthrough + case token.STRICT_EQUAL: + if x.kind != y.kind { + result = false + } else { + kindEqualKind = true + } + case token.NOT_EQUAL: + negate = true + fallthrough + case token.EQUAL: + if x.kind == y.kind { + kindEqualKind = true + } else if x.kind <= valueNull && y.kind <= valueNull { + result = true + } else if x.kind <= valueNull || y.kind <= valueNull { + result = false + } else if x.kind <= valueString && y.kind <= valueString { + result = x.float64() == y.float64() + } else if x.kind == valueBoolean { + result = self.calculateComparison(token.EQUAL, toValue_float64(x.float64()), y) + } else if y.kind == valueBoolean { + result = self.calculateComparison(token.EQUAL, x, toValue_float64(y.float64())) + } else if x.kind == valueObject { + result = self.calculateComparison(token.EQUAL, toPrimitive(x), y) + } else if y.kind == valueObject { + result = self.calculateComparison(token.EQUAL, x, toPrimitive(y)) + } else { + panic(hereBeDragons("Unable to test for equality: %v ==? %v", x, y)) + } + default: + panic(fmt.Errorf("Unknown comparator %s", comparator.String())) + } + + if kindEqualKind { + switch x.kind { + case valueUndefined, valueNull: + result = true + case valueNumber: + x := x.float64() + y := y.float64() + if math.IsNaN(x) || math.IsNaN(y) { + result = false + } else { + result = x == y + } + case valueString: + result = x.string() == y.string() + case valueBoolean: + result = x.bool() == y.bool() + case valueObject: + result = x._object() == y._object() + default: + goto ERROR + } + } + + if negate { + result = !result + } + + return result + +ERROR: + panic(hereBeDragons("%v (%v) %s %v (%v)", x, x.kind, comparator, y, y.kind)) +} diff --git a/vendor/github.com/robertkrimen/otto/file/README.markdown b/vendor/github.com/robertkrimen/otto/file/README.markdown new file mode 100644 index 0000000..79757ba --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/file/README.markdown @@ -0,0 +1,110 @@ +# file +-- + import "github.com/robertkrimen/otto/file" + +Package file encapsulates the file abstractions used by the ast & parser. + +## Usage + +#### type File + +```go +type File struct { +} +``` + + +#### func NewFile + +```go +func NewFile(filename, src string, base int) *File +``` + +#### func (*File) Base + +```go +func (fl *File) Base() int +``` + +#### func (*File) Name + +```go +func (fl *File) Name() string +``` + +#### func (*File) Source + +```go +func (fl *File) Source() string +``` + +#### 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) File + +```go +func (self *FileSet) File(idx Idx) *File +``` + +#### 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 diff --git a/vendor/github.com/robertkrimen/otto/file/file.go b/vendor/github.com/robertkrimen/otto/file/file.go new file mode 100644 index 0000000..76524ac --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/file/file.go @@ -0,0 +1,135 @@ +// 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{ + name: 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 +} + +func (self *FileSet) File(idx Idx) *File { + for _, file := range self.files { + if idx <= Idx(file.base+len(file.src)) { + return file + } + } + return nil +} + +// 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.name + 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 { + name string + src string + base int // This will always be 1 or greater +} + +func NewFile(filename, src string, base int) *File { + return &File{ + name: filename, + src: src, + base: base, + } +} + +func (fl *File) Name() string { + return fl.name +} + +func (fl *File) Source() string { + return fl.src +} + +func (fl *File) Base() int { + return fl.base +} diff --git a/vendor/github.com/robertkrimen/otto/global.go b/vendor/github.com/robertkrimen/otto/global.go new file mode 100644 index 0000000..4f03531 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/global.go @@ -0,0 +1,221 @@ +package otto + +import ( + "strconv" + "time" +) + +var ( + prototypeValueObject = interface{}(nil) + prototypeValueFunction = _nativeFunctionObject{ + call: func(_ FunctionCall) Value { + return Value{} + }, + } + prototypeValueString = _stringASCII("") + // TODO Make this just false? + prototypeValueBoolean = Value{ + kind: valueBoolean, + value: false, + } + prototypeValueNumber = Value{ + kind: valueNumber, + value: 0, + } + prototypeValueDate = _dateObject{ + epoch: 0, + isNaN: false, + time: time.Unix(0, 0).UTC(), + value: Value{ + kind: valueNumber, + value: 0, + }, + } + prototypeValueRegExp = _regExpObject{ + regularExpression: nil, + global: false, + ignoreCase: false, + multiline: false, + source: "", + flags: "", + } +) + +func newContext() *_runtime { + + self := &_runtime{} + + self.globalStash = self.newObjectStash(nil, nil) + self.globalObject = self.globalStash.object + + _newContext(self) + + self.eval = self.globalObject.property["eval"].value.(Value).value.(*_object) + self.globalObject.prototype = self.global.ObjectPrototype + + return self +} + +func (runtime *_runtime) newBaseObject() *_object { + self := newObject(runtime, "") + return self +} + +func (runtime *_runtime) newClassObject(class string) *_object { + return newObject(runtime, class) +} + +func (runtime *_runtime) newPrimitiveObject(class string, value Value) *_object { + self := runtime.newClassObject(class) + self.value = value + return self +} + +func (self *_object) primitiveValue() Value { + switch value := self.value.(type) { + case Value: + return value + case _stringObject: + return toValue_string(value.String()) + } + return Value{} +} + +func (self *_object) hasPrimitive() bool { + switch self.value.(type) { + case Value, _stringObject: + return true + } + return false +} + +func (runtime *_runtime) newObject() *_object { + self := runtime.newClassObject("Object") + self.prototype = runtime.global.ObjectPrototype + return self +} + +func (runtime *_runtime) newArray(length uint32) *_object { + self := runtime.newArrayObject(length) + self.prototype = runtime.global.ArrayPrototype + return self +} + +func (runtime *_runtime) newArrayOf(valueArray []Value) *_object { + self := runtime.newArray(uint32(len(valueArray))) + for index, value := range valueArray { + if value.isEmpty() { + continue + } + self.defineProperty(strconv.FormatInt(int64(index), 10), value, 0111, false) + } + return self +} + +func (runtime *_runtime) newString(value Value) *_object { + self := runtime.newStringObject(value) + self.prototype = runtime.global.StringPrototype + return self +} + +func (runtime *_runtime) newBoolean(value Value) *_object { + self := runtime.newBooleanObject(value) + self.prototype = runtime.global.BooleanPrototype + return self +} + +func (runtime *_runtime) newNumber(value Value) *_object { + self := runtime.newNumberObject(value) + self.prototype = runtime.global.NumberPrototype + return self +} + +func (runtime *_runtime) newRegExp(patternValue Value, flagsValue Value) *_object { + + pattern := "" + flags := "" + if object := patternValue._object(); object != nil && object.class == "RegExp" { + if flagsValue.IsDefined() { + panic(runtime.panicTypeError("Cannot supply flags when constructing one RegExp from another")) + } + regExp := object.regExpValue() + pattern = regExp.source + flags = regExp.flags + } else { + if patternValue.IsDefined() { + pattern = patternValue.string() + } + if flagsValue.IsDefined() { + flags = flagsValue.string() + } + } + + return runtime._newRegExp(pattern, flags) +} + +func (runtime *_runtime) _newRegExp(pattern string, flags string) *_object { + self := runtime.newRegExpObject(pattern, flags) + self.prototype = runtime.global.RegExpPrototype + return self +} + +// TODO Should (probably) be one argument, right? This is redundant +func (runtime *_runtime) newDate(epoch float64) *_object { + self := runtime.newDateObject(epoch) + self.prototype = runtime.global.DatePrototype + return self +} + +func (runtime *_runtime) newError(name string, message Value) *_object { + var self *_object + switch name { + case "EvalError": + return runtime.newEvalError(message) + case "TypeError": + return runtime.newTypeError(message) + case "RangeError": + return runtime.newRangeError(message) + case "ReferenceError": + return runtime.newReferenceError(message) + case "SyntaxError": + return runtime.newSyntaxError(message) + case "URIError": + return runtime.newURIError(message) + } + + self = runtime.newErrorObject(name, message) + self.prototype = runtime.global.ErrorPrototype + if name != "" { + self.defineProperty("name", toValue_string(name), 0111, false) + } + return self +} + +func (runtime *_runtime) newNativeFunction(name string, _nativeFunction _nativeFunction) *_object { + self := runtime.newNativeFunctionObject(name, _nativeFunction, 0) + 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 (runtime *_runtime) newNodeFunction(node *_nodeFunctionLiteral, scopeEnvironment _stash) *_object { + // TODO Implement 13.2 fully + self := runtime.newNodeFunctionObject(node, scopeEnvironment) + self.prototype = runtime.global.FunctionPrototype + prototype := runtime.newObject() + self.defineProperty("prototype", toValue_object(prototype), 0100, false) + prototype.defineProperty("constructor", toValue_object(self), 0101, false) + return self +} + +// FIXME Only in one place... +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 +} diff --git a/vendor/github.com/robertkrimen/otto/inline b/vendor/github.com/robertkrimen/otto/inline new file mode 100755 index 0000000..c3620b4 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/inline @@ -0,0 +1,1086 @@ +#!/usr/bin/env perl + +my $_fmt; +$_fmt = "gofmt"; +$_fmt = "cat -n" if "cat" eq ($ARGV[0] || ""); + +use strict; +use warnings; +use IO::File; + +my $self = __PACKAGE__; + +sub functionLabel ($) { + return "$_[0]_function"; +} + +sub trim ($) { + local $_ = shift; + s/^\s*//, s/\s*$// for $_; + return $_; +} + +open my $fmt, "|-", "$_fmt" or die $!; + +$fmt->print(<<_END_); +package otto + +import ( + "math" +) + +func _newContext(runtime *_runtime) { +@{[ join "\n", $self->newContext() ]} +} + +func newConsoleObject(runtime *_runtime) *_object { +@{[ join "\n", $self->newConsoleObject() ]} +} +_END_ + +for (qw/int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float32 float64/) { + $fmt->print(<<_END_); + +func toValue_$_(value $_) Value { + return Value{ + kind: valueNumber, + value: value, + } +} +_END_ +} + +$fmt->print(<<_END_); + +func toValue_string(value string) Value { + return Value{ + kind: valueString, + value: value, + } +} + +func toValue_string16(value []uint16) Value { + return Value{ + kind: valueString, + value: value, + } +} + +func toValue_bool(value bool) Value { + return Value{ + kind: valueBoolean, + value: value, + } +} + +func toValue_object(value *_object) Value { + return Value{ + kind: valueObject, + value: value, + } +} +_END_ + +close $fmt; + +sub newConsoleObject { + my $self = shift; + + return + $self->block(sub { + my $class = "Console"; + my @got = $self->functionDeclare( + $class, + "log", 0, + "debug:log", 0, + "info:log", 0, + "error", 0, + "warn:error", 0, + "dir", 0, + "time", 0, + "timeEnd", 0, + "trace", 0, + "assert", 0, + ); + return + "return @{[ $self->newObject(@got) ]}" + }), + ; +} + +sub newContext { + my $self = shift; + return + # ObjectPrototype + $self->block(sub { + my $class = "Object"; + return + ".${class}Prototype =", + $self->globalPrototype( + $class, + "_classObject", + undef, + "prototypeValueObject", + ), + }), + + # FunctionPrototype + $self->block(sub { + my $class = "Function"; + return + ".${class}Prototype =", + $self->globalPrototype( + $class, + "_classObject", + ".ObjectPrototype", + "prototypeValueFunction", + ), + }), + + # ObjectPrototype + $self->block(sub { + my $class = "Object"; + my @got = $self->functionDeclare( + $class, + "valueOf", 0, + "toString", 0, + "toLocaleString", 0, + "hasOwnProperty", 1, + "isPrototypeOf", 1, + "propertyIsEnumerable", 1, + ); + my @propertyMap = $self->propertyMap( + @got, + $self->property("constructor", undef), + ); + my $propertyOrder = $self->propertyOrder(@propertyMap); + $propertyOrder =~ s/^propertyOrder: //; + return + ".${class}Prototype.property =", @propertyMap, + ".${class}Prototype.propertyOrder =", $propertyOrder, + }), + + # FunctionPrototype + $self->block(sub { + my $class = "Function"; + my @got = $self->functionDeclare( + $class, + "toString", 0, + "apply", 2, + "call", 1, + "bind", 1, + ); + my @propertyMap = $self->propertyMap( + @got, + $self->property("constructor", undef), + $self->property("length", $self->numberValue(0), "0"), + ); + my $propertyOrder = $self->propertyOrder(@propertyMap); + $propertyOrder =~ s/^propertyOrder: //; + return + ".${class}Prototype.property =", @propertyMap, + ".${class}Prototype.propertyOrder =", $propertyOrder, + }), + + # Object + $self->block(sub { + my $class = "Object"; + return + ".$class =", + $self->globalFunction( + $class, + 1, + $self->functionDeclare( + $class, + "getPrototypeOf", 1, + "getOwnPropertyDescriptor", 2, + "defineProperty", 3, + "defineProperties", 2, + "create", 2, + "isExtensible", 1, + "preventExtensions", 1, + "isSealed", 1, + "seal", 1, + "isFrozen", 1, + "freeze", 1, + "keys", 1, + "getOwnPropertyNames", 1, + ), + ), + }), + + # Function + $self->block(sub { + my $class = "Function"; + return + "Function :=", + $self->globalFunction( + $class, + 1, + ), + ".$class = Function", + }), + + # Array + $self->block(sub { + my $class = "Array"; + my @got = $self->functionDeclare( + $class, + "toString", 0, + "toLocaleString", 0, + "concat", 1, + "join", 1, + "splice", 2, + "shift", 0, + "pop", 0, + "push", 1, + "slice", 2, + "unshift", 1, + "reverse", 0, + "sort", 1, + "indexOf", 1, + "lastIndexOf", 1, + "every", 1, + "some", 1, + "forEach", 1, + "map", 1, + "filter", 1, + "reduce", 1, + "reduceRight", 1, + ); + return + ".${class}Prototype =", + $self->globalPrototype( + $class, + "_classArray", + ".ObjectPrototype", + undef, + $self->property("length", $self->numberValue("uint32(0)"), "0100"), + @got, + ), + ".$class =", + $self->globalFunction( + $class, + 1, + $self->functionDeclare( + $class, + "isArray", 1, + ), + ), + }), + + # String + $self->block(sub { + my $class = "String"; + my @got = $self->functionDeclare( + $class, + "toString", 0, + "valueOf", 0, + "charAt", 1, + "charCodeAt", 1, + "concat", 1, + "indexOf", 1, + "lastIndexOf", 1, + "match", 1, + "replace", 2, + "search", 1, + "split", 2, + "slice", 2, + "substring", 2, + "toLowerCase", 0, + "toUpperCase", 0, + "substr", 2, + "trim", 0, + "trimLeft", 0, + "trimRight", 0, + "localeCompare", 1, + "toLocaleLowerCase", 0, + "toLocaleUpperCase", 0, + ); + return + ".${class}Prototype =", + $self->globalPrototype( + $class, + "_classString", + ".ObjectPrototype", + "prototypeValueString", + $self->property("length", $self->numberValue("int(0)"), "0"), + @got, + ), + ".$class =", + $self->globalFunction( + $class, + 1, + $self->functionDeclare( + $class, + "fromCharCode", 1, + ), + ), + }), + + # Boolean + $self->block(sub { + my $class = "Boolean"; + my @got = $self->functionDeclare( + $class, + "toString", 0, + "valueOf", 0, + ); + return + ".${class}Prototype =", + $self->globalPrototype( + $class, + "_classObject", + ".ObjectPrototype", + "prototypeValueBoolean", + @got, + ), + ".$class =", + $self->globalFunction( + $class, + 1, + $self->functionDeclare( + $class, + ), + ), + }), + + # Number + $self->block(sub { + my $class = "Number"; + my @got = $self->functionDeclare( + $class, + "toString", 0, + "valueOf", 0, + "toFixed", 1, + "toExponential", 1, + "toPrecision", 1, + "toLocaleString", 1, + ); + return + ".${class}Prototype =", + $self->globalPrototype( + $class, + "_classObject", + ".ObjectPrototype", + "prototypeValueNumber", + @got, + ), + ".$class =", + $self->globalFunction( + $class, + 1, + $self->functionDeclare( + $class, + ), + $self->numberConstantDeclare( + "MAX_VALUE", "math.MaxFloat64", + "MIN_VALUE", "math.SmallestNonzeroFloat64", + "NaN", "math.NaN()", + "NEGATIVE_INFINITY", "math.Inf(-1)", + "POSITIVE_INFINITY", "math.Inf(+1)", + ), + ), + }), + + # Math + $self->block(sub { + my $class = "Math"; + return + ".$class =", + $self->globalObject( + $class, + $self->functionDeclare( + $class, + "abs", 1, + "acos", 1, + "asin", 1, + "atan", 1, + "atan2", 1, + "ceil", 1, + "cos", 1, + "exp", 1, + "floor", 1, + "log", 1, + "max", 2, + "min", 2, + "pow", 2, + "random", 0, + "round", 1, + "sin", 1, + "sqrt", 1, + "tan", 1, + ), + $self->numberConstantDeclare( + "E", "math.E", + "LN10", "math.Ln10", + "LN2", "math.Ln2", + "LOG2E", "math.Log2E", + "LOG10E", "math.Log10E", + "PI", "math.Pi", + "SQRT1_2", "sqrt1_2", + "SQRT2", "math.Sqrt2", + ) + ), + }), + + # Date + $self->block(sub { + my $class = "Date"; + my @got = $self->functionDeclare( + $class, + "toString", 0, + "toDateString", 0, + "toTimeString", 0, + "toUTCString", 0, + "toISOString", 0, + "toJSON", 1, + "toGMTString", 0, + "toLocaleString", 0, + "toLocaleDateString", 0, + "toLocaleTimeString", 0, + "valueOf", 0, + "getTime", 0, + "getYear", 0, + "getFullYear", 0, + "getUTCFullYear", 0, + "getMonth", 0, + "getUTCMonth", 0, + "getDate", 0, + "getUTCDate", 0, + "getDay", 0, + "getUTCDay", 0, + "getHours", 0, + "getUTCHours", 0, + "getMinutes", 0, + "getUTCMinutes", 0, + "getSeconds", 0, + "getUTCSeconds", 0, + "getMilliseconds", 0, + "getUTCMilliseconds", 0, + "getTimezoneOffset", 0, + "setTime", 1, + "setMilliseconds", 1, + "setUTCMilliseconds", 1, + "setSeconds", 2, + "setUTCSeconds", 2, + "setMinutes", 3, + "setUTCMinutes", 3, + "setHours", 4, + "setUTCHours", 4, + "setDate", 1, + "setUTCDate", 1, + "setMonth", 2, + "setUTCMonth", 2, + "setYear", 1, + "setFullYear", 3, + "setUTCFullYear", 3, + ); + return + ".${class}Prototype =", + $self->globalPrototype( + $class, + "_classObject", + ".ObjectPrototype", + "prototypeValueDate", + @got, + ), + ".$class =", + $self->globalFunction( + $class, + 7, + $self->functionDeclare( + $class, + "parse", 1, + "UTC", 7, + "now", 0, + ), + ), + }), + + # RegExp + $self->block(sub { + my $class = "RegExp"; + my @got = $self->functionDeclare( + $class, + "toString", 0, + "exec", 1, + "test", 1, + "compile", 1, + ); + return + ".${class}Prototype =", + $self->globalPrototype( + $class, + "_classObject", + ".ObjectPrototype", + "prototypeValueRegExp", + @got, + ), + ".$class =", + $self->globalFunction( + $class, + 2, + $self->functionDeclare( + $class, + ), + ), + }), + + # Error + $self->block(sub { + my $class = "Error"; + my @got = $self->functionDeclare( + $class, + "toString", 0, + ); + return + ".${class}Prototype =", + $self->globalPrototype( + $class, + "_classObject", + ".ObjectPrototype", + undef, + @got, + $self->property("name", $self->stringValue("Error")), + $self->property("message", $self->stringValue("")), + ), + ".$class =", + $self->globalFunction( + $class, + 1, + $self->functionDeclare( + $class, + ), + ), + }), + + (map { + my $class = "${_}Error"; + $self->block(sub { + my @got = $self->functionDeclare( + $class, + ); + return + ".${class}Prototype =", + $self->globalPrototype( + $class, + "_classObject", + ".ErrorPrototype", + undef, + @got, + $self->property("name", $self->stringValue($class)), + ), + ".$class =", + $self->globalFunction( + $class, + 1, + $self->functionDeclare( + $class, + ), + ), + }); + } qw/Eval Type Range Reference Syntax URI/), + + # JSON + $self->block(sub { + my $class = "JSON"; + return + ".$class =", + $self->globalObject( + $class, + $self->functionDeclare( + $class, + "parse", 2, + "stringify", 3, + ), + ), + }), + + # Global + $self->block(sub { + my $class = "Global"; + my @got = $self->functionDeclare( + $class, + "eval", 1, + "parseInt", 2, + "parseFloat", 1, + "isNaN", 1, + "isFinite", 1, + "decodeURI", 1, + "decodeURIComponent", 1, + "encodeURI", 1, + "encodeURIComponent", 1, + "escape", 1, + "unescape", 1, + ); + my @propertyMap = $self->propertyMap( + @got, + $self->globalDeclare( + "Object", + "Function", + "Array", + "String", + "Boolean", + "Number", + "Math", + "Date", + "RegExp", + "Error", + "EvalError", + "TypeError", + "RangeError", + "ReferenceError", + "SyntaxError", + "URIError", + "JSON", + ), + $self->property("undefined", $self->undefinedValue(), "0"), + $self->property("NaN", $self->numberValue("math.NaN()"), "0"), + $self->property("Infinity", $self->numberValue("math.Inf(+1)"), "0"), + ); + my $propertyOrder = $self->propertyOrder(@propertyMap); + $propertyOrder =~ s/^propertyOrder: //; + return + "runtime.globalObject.property =", + @propertyMap, + "runtime.globalObject.propertyOrder =", + $propertyOrder, + ; + }), + ; +} + +sub propertyMap { + my $self = shift; + return "map[string]_property{", (join ",\n", @_, ""), "}", +} + +our (@preblock, @postblock); +sub block { + my $self = shift; + local @preblock = (); + local @postblock = (); + my @input = $_[0]->(); + my @output; + while (@input) { + local $_ = shift @input; + if (m/^\./) { + $_ = "runtime.global$_"; + } + if (m/ :?=$/) { + $_ .= shift @input; + } + push @output, $_; + } + return + "{", + @preblock, + @output, + @postblock, + "}", + ; +} + +sub numberConstantDeclare { + my $self = shift; + my @got; + while (@_) { + my $name = shift; + my $value = shift; + push @got, $self->property($name, $self->numberValue($value), "0"), + } + return @got; +} + +sub functionDeclare { + my $self = shift; + my $class = shift; + my $builtin = "builtin${class}"; + my @got; + while (@_) { + my $name = shift; + my $length = shift; + $name = $self->newFunction($name, "${builtin}_", $length); + push @got, $self->functionProperty($name), + } + return @got; +} + +sub globalDeclare { + my $self = shift; + my @got; + while (@_) { + my $name = shift; + push @got, $self->property($name, $self->objectValue("runtime.global.$name"), "0101"), + } + return @got; +} + +sub propertyOrder { + my $self = shift; + my $propertyMap = join "", @_; + + my (@keys) = $propertyMap =~ m/("\w+"):/g; + my $propertyOrder = + join "\n", "propertyOrder: []string{", (join ",\n", @keys, ""), "}"; + return $propertyOrder; +} + +sub globalObject { + my $self = shift; + my $name = shift; + + my $propertyMap = ""; + if (@_) { + $propertyMap = join "\n", $self->propertyMap(@_); + my $propertyOrder = $self->propertyOrder($propertyMap); + $propertyMap = "property: $propertyMap,\n$propertyOrder,"; + } + + return trim <<_END_; +&_object{ + runtime: runtime, + class: "$name", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + $propertyMap +} +_END_ +} + +sub globalFunction { + my $self = shift; + my $name = shift; + my $length = shift; + + my $builtin = "builtin${name}"; + my $builtinNew = "builtinNew${name}"; + my $prototype = "runtime.global.${name}Prototype"; + my $propertyMap = ""; + unshift @_, + $self->property("length", $self->numberValue($length), "0"), + $self->property("prototype", $self->objectValue($prototype), "0"), + ; + + if (@_) { + $propertyMap = join "\n", $self->propertyMap(@_); + my $propertyOrder = $self->propertyOrder($propertyMap); + $propertyMap = "property: $propertyMap,\n$propertyOrder,"; + } + + push @postblock, $self->statement( + "$prototype.property[\"constructor\"] =", + $self->property(undef, $self->objectValue("runtime.global.${name}"), "0101"), + ); + + return trim <<_END_; +&_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: @{[ $self->nativeFunctionOf($name, $builtin, $builtinNew) ]}, + $propertyMap +} +_END_ +} + +sub nativeCallFunction { + my $self = shift; + my $name = shift; + my $func = shift; + return trim <<_END_; +_nativeCallFunction{ "$name", $func } +_END_ +} + +sub globalPrototype { + my $self = shift; + my $class = shift; + my $classObject = shift; + my $prototype = shift; + my $value = shift; + + if (!defined $prototype) { + $prototype = "nil"; + } + + if (!defined $value) { + $value = "nil"; + } + + if ($prototype =~ m/^\./) { + $prototype = "runtime.global$prototype"; + } + + my $propertyMap = ""; + if (@_) { + $propertyMap = join "\n", $self->propertyMap(@_); + my $propertyOrder = $self->propertyOrder($propertyMap); + $propertyMap = "property: $propertyMap,\n$propertyOrder,"; + } + + return trim <<_END_; +&_object{ + runtime: runtime, + class: "$class", + objectClass: $classObject, + prototype: $prototype, + extensible: true, + value: $value, + $propertyMap +} +_END_ +} + +sub newFunction { + my $self = shift; + my $name = shift; + my $func = shift; + my $length = shift; + + my @name = ($name, $name); + if ($name =~ m/^(\w+):(\w+)$/) { + @name = ($1, $2); + $name = $name[0]; + } + + if ($func =~ m/^builtin\w+_$/) { + $func = "$func$name[1]"; + } + + my $propertyOrder = ""; + my @propertyMap = ( + $self->property("length", $self->numberValue($length), "0"), + ); + + if (@propertyMap) { + $propertyOrder = $self->propertyOrder(@propertyMap); + $propertyOrder = "$propertyOrder,"; + } + + my $label = functionLabel($name); + push @preblock, $self->statement( + "$label := @{[ trim <<_END_ ]}", +&_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: @{[ join "\n", $self->propertyMap(@propertyMap) ]}, + $propertyOrder + value: @{[ $self->nativeFunctionOf($name, $func) ]}, +} +_END_ + ); + + return $name; +} + +sub newObject { + my $self = shift; + + my $propertyMap = join "\n", $self->propertyMap(@_); + my $propertyOrder = $self->propertyOrder($propertyMap); + + return trim <<_END_; +&_object{ + runtime: runtime, + class: "Object", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + property: $propertyMap, + $propertyOrder, +} +_END_ +} + +sub newPrototypeObject { + my $self = shift; + my $class = shift; + my $objectClass = shift; + my $value = shift; + if (defined $value) { + $value = "value: $value,"; + } + + my $propertyMap = join "\n", $self->propertyMap(@_); + my $propertyOrder = $self->propertyOrder($propertyMap); + + return trim <<_END_; +&_object{ + runtime: runtime, + class: "$class", + objectClass: $objectClass, + prototype: runtime.global.ObjectPrototype, + extensible: true, + property: $propertyMap, + $propertyOrder, + $value +} +_END_ +} + +sub functionProperty { + my $self = shift; + my $name = shift; + + return $self->property( + $name, + $self->objectValue(functionLabel($name)) + ); +} + +sub statement { + my $self = shift; + return join "\n", @_; +} + +sub functionOf { + my $self = shift; + my $call = shift; + my $construct = shift; + if ($construct) { + $construct = "construct: $construct,"; + } else { + $construct = ""; + } + + return trim <<_END_ +_functionObject{ + call: $call, + $construct +} +_END_ +} + +sub nativeFunctionOf { + my $self = shift; + my $name = shift; + my $call = shift; + my $construct = shift; + if ($construct) { + $construct = "construct: $construct,"; + } else { + $construct = ""; + } + + return trim <<_END_ +_nativeFunctionObject{ + name: "$name", + call: $call, + $construct +} +_END_ +} + +sub nameProperty { + my $self = shift; + my $name = shift; + my $value = shift; + + return trim <<_END_; +"$name": _property{ + mode: 0101, + value: $value, +} +_END_ +} + +sub numberValue { + my $self = shift; + my $value = shift; + return trim <<_END_; +Value{ + kind: valueNumber, + value: $value, +} +_END_ +} + +sub property { + my $self = shift; + my $name = shift; + my $value = shift; + my $mode = shift; + $mode = "0101" unless defined $mode; + if (! defined $value) { + $value = "Value{}"; + } + if (defined $name) { + return trim <<_END_; +"$name": _property{ + mode: $mode, + value: $value, +} +_END_ + } else { + return trim <<_END_; +_property{ + mode: $mode, + value: $value, +} +_END_ + } + +} + +sub objectProperty { + my $self = shift; + my $name = shift; + my $value = shift; + + return trim <<_END_; +"$name": _property{ + mode: 0101, + value: @{[ $self->objectValue($value)]}, +} +_END_ +} + +sub objectValue { + my $self = shift; + my $value = shift; + return trim <<_END_ +Value{ + kind: valueObject, + value: $value, +} +_END_ +} + +sub stringValue { + my $self = shift; + my $value = shift; + return trim <<_END_ +Value{ + kind: valueString, + value: "$value", +} +_END_ +} + +sub booleanValue { + my $self = shift; + my $value = shift; + return trim <<_END_ +Value{ + kind: valueBoolean, + value: $value, +} +_END_ +} + +sub undefinedValue { + my $self = shift; + return trim <<_END_ +Value{ + kind: valueUndefined, +} +_END_ +} diff --git a/vendor/github.com/robertkrimen/otto/inline.go b/vendor/github.com/robertkrimen/otto/inline.go new file mode 100644 index 0000000..6e5df83 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/inline.go @@ -0,0 +1,6649 @@ +package otto + +import ( + "math" +) + +func _newContext(runtime *_runtime) { + { + runtime.global.ObjectPrototype = &_object{ + runtime: runtime, + class: "Object", + objectClass: _classObject, + prototype: nil, + extensible: true, + value: prototypeValueObject, + } + } + { + runtime.global.FunctionPrototype = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + value: prototypeValueFunction, + } + } + { + valueOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "valueOf", + call: builtinObject_valueOf, + }, + } + toString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toString", + call: builtinObject_toString, + }, + } + toLocaleString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toLocaleString", + call: builtinObject_toLocaleString, + }, + } + hasOwnProperty_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "hasOwnProperty", + call: builtinObject_hasOwnProperty, + }, + } + isPrototypeOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "isPrototypeOf", + call: builtinObject_isPrototypeOf, + }, + } + propertyIsEnumerable_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "propertyIsEnumerable", + call: builtinObject_propertyIsEnumerable, + }, + } + runtime.global.ObjectPrototype.property = map[string]_property{ + "valueOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: valueOf_function, + }, + }, + "toString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toString_function, + }, + }, + "toLocaleString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toLocaleString_function, + }, + }, + "hasOwnProperty": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: hasOwnProperty_function, + }, + }, + "isPrototypeOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: isPrototypeOf_function, + }, + }, + "propertyIsEnumerable": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: propertyIsEnumerable_function, + }, + }, + "constructor": _property{ + mode: 0101, + value: Value{}, + }, + } + runtime.global.ObjectPrototype.propertyOrder = []string{ + "valueOf", + "toString", + "toLocaleString", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "constructor", + } + } + { + toString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toString", + call: builtinFunction_toString, + }, + } + apply_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "apply", + call: builtinFunction_apply, + }, + } + call_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "call", + call: builtinFunction_call, + }, + } + bind_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "bind", + call: builtinFunction_bind, + }, + } + runtime.global.FunctionPrototype.property = map[string]_property{ + "toString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toString_function, + }, + }, + "apply": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: apply_function, + }, + }, + "call": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: call_function, + }, + }, + "bind": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: bind_function, + }, + }, + "constructor": _property{ + mode: 0101, + value: Value{}, + }, + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + } + runtime.global.FunctionPrototype.propertyOrder = []string{ + "toString", + "apply", + "call", + "bind", + "constructor", + "length", + } + } + { + getPrototypeOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getPrototypeOf", + call: builtinObject_getPrototypeOf, + }, + } + getOwnPropertyDescriptor_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getOwnPropertyDescriptor", + call: builtinObject_getOwnPropertyDescriptor, + }, + } + defineProperty_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 3, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "defineProperty", + call: builtinObject_defineProperty, + }, + } + defineProperties_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "defineProperties", + call: builtinObject_defineProperties, + }, + } + create_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "create", + call: builtinObject_create, + }, + } + isExtensible_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "isExtensible", + call: builtinObject_isExtensible, + }, + } + preventExtensions_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "preventExtensions", + call: builtinObject_preventExtensions, + }, + } + isSealed_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "isSealed", + call: builtinObject_isSealed, + }, + } + seal_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "seal", + call: builtinObject_seal, + }, + } + isFrozen_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "isFrozen", + call: builtinObject_isFrozen, + }, + } + freeze_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "freeze", + call: builtinObject_freeze, + }, + } + keys_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "keys", + call: builtinObject_keys, + }, + } + getOwnPropertyNames_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getOwnPropertyNames", + call: builtinObject_getOwnPropertyNames, + }, + } + runtime.global.Object = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "Object", + call: builtinObject, + construct: builtinNewObject, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.ObjectPrototype, + }, + }, + "getPrototypeOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getPrototypeOf_function, + }, + }, + "getOwnPropertyDescriptor": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getOwnPropertyDescriptor_function, + }, + }, + "defineProperty": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: defineProperty_function, + }, + }, + "defineProperties": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: defineProperties_function, + }, + }, + "create": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: create_function, + }, + }, + "isExtensible": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: isExtensible_function, + }, + }, + "preventExtensions": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: preventExtensions_function, + }, + }, + "isSealed": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: isSealed_function, + }, + }, + "seal": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: seal_function, + }, + }, + "isFrozen": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: isFrozen_function, + }, + }, + "freeze": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: freeze_function, + }, + }, + "keys": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: keys_function, + }, + }, + "getOwnPropertyNames": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getOwnPropertyNames_function, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + "getPrototypeOf", + "getOwnPropertyDescriptor", + "defineProperty", + "defineProperties", + "create", + "isExtensible", + "preventExtensions", + "isSealed", + "seal", + "isFrozen", + "freeze", + "keys", + "getOwnPropertyNames", + }, + } + runtime.global.ObjectPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Object, + }, + } + } + { + Function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "Function", + call: builtinFunction, + construct: builtinNewFunction, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.FunctionPrototype, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + }, + } + runtime.global.Function = Function + runtime.global.FunctionPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Function, + }, + } + } + { + toString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toString", + call: builtinArray_toString, + }, + } + toLocaleString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toLocaleString", + call: builtinArray_toLocaleString, + }, + } + concat_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "concat", + call: builtinArray_concat, + }, + } + join_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "join", + call: builtinArray_join, + }, + } + splice_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "splice", + call: builtinArray_splice, + }, + } + shift_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "shift", + call: builtinArray_shift, + }, + } + pop_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "pop", + call: builtinArray_pop, + }, + } + push_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "push", + call: builtinArray_push, + }, + } + slice_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "slice", + call: builtinArray_slice, + }, + } + unshift_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "unshift", + call: builtinArray_unshift, + }, + } + reverse_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "reverse", + call: builtinArray_reverse, + }, + } + sort_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "sort", + call: builtinArray_sort, + }, + } + indexOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "indexOf", + call: builtinArray_indexOf, + }, + } + lastIndexOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "lastIndexOf", + call: builtinArray_lastIndexOf, + }, + } + every_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "every", + call: builtinArray_every, + }, + } + some_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "some", + call: builtinArray_some, + }, + } + forEach_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "forEach", + call: builtinArray_forEach, + }, + } + map_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "map", + call: builtinArray_map, + }, + } + filter_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "filter", + call: builtinArray_filter, + }, + } + reduce_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "reduce", + call: builtinArray_reduce, + }, + } + reduceRight_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "reduceRight", + call: builtinArray_reduceRight, + }, + } + isArray_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "isArray", + call: builtinArray_isArray, + }, + } + runtime.global.ArrayPrototype = &_object{ + runtime: runtime, + class: "Array", + objectClass: _classArray, + prototype: runtime.global.ObjectPrototype, + extensible: true, + value: nil, + property: map[string]_property{ + "length": _property{ + mode: 0100, + value: Value{ + kind: valueNumber, + value: uint32(0), + }, + }, + "toString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toString_function, + }, + }, + "toLocaleString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toLocaleString_function, + }, + }, + "concat": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: concat_function, + }, + }, + "join": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: join_function, + }, + }, + "splice": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: splice_function, + }, + }, + "shift": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: shift_function, + }, + }, + "pop": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: pop_function, + }, + }, + "push": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: push_function, + }, + }, + "slice": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: slice_function, + }, + }, + "unshift": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: unshift_function, + }, + }, + "reverse": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: reverse_function, + }, + }, + "sort": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: sort_function, + }, + }, + "indexOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: indexOf_function, + }, + }, + "lastIndexOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: lastIndexOf_function, + }, + }, + "every": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: every_function, + }, + }, + "some": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: some_function, + }, + }, + "forEach": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: forEach_function, + }, + }, + "map": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: map_function, + }, + }, + "filter": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: filter_function, + }, + }, + "reduce": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: reduce_function, + }, + }, + "reduceRight": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: reduceRight_function, + }, + }, + }, + propertyOrder: []string{ + "length", + "toString", + "toLocaleString", + "concat", + "join", + "splice", + "shift", + "pop", + "push", + "slice", + "unshift", + "reverse", + "sort", + "indexOf", + "lastIndexOf", + "every", + "some", + "forEach", + "map", + "filter", + "reduce", + "reduceRight", + }, + } + runtime.global.Array = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "Array", + call: builtinArray, + construct: builtinNewArray, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.ArrayPrototype, + }, + }, + "isArray": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: isArray_function, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + "isArray", + }, + } + runtime.global.ArrayPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Array, + }, + } + } + { + toString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toString", + call: builtinString_toString, + }, + } + valueOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "valueOf", + call: builtinString_valueOf, + }, + } + charAt_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "charAt", + call: builtinString_charAt, + }, + } + charCodeAt_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "charCodeAt", + call: builtinString_charCodeAt, + }, + } + concat_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "concat", + call: builtinString_concat, + }, + } + indexOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "indexOf", + call: builtinString_indexOf, + }, + } + lastIndexOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "lastIndexOf", + call: builtinString_lastIndexOf, + }, + } + match_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "match", + call: builtinString_match, + }, + } + replace_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "replace", + call: builtinString_replace, + }, + } + search_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "search", + call: builtinString_search, + }, + } + split_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "split", + call: builtinString_split, + }, + } + slice_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "slice", + call: builtinString_slice, + }, + } + substring_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "substring", + call: builtinString_substring, + }, + } + toLowerCase_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toLowerCase", + call: builtinString_toLowerCase, + }, + } + toUpperCase_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toUpperCase", + call: builtinString_toUpperCase, + }, + } + substr_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "substr", + call: builtinString_substr, + }, + } + trim_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "trim", + call: builtinString_trim, + }, + } + trimLeft_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "trimLeft", + call: builtinString_trimLeft, + }, + } + trimRight_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "trimRight", + call: builtinString_trimRight, + }, + } + localeCompare_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "localeCompare", + call: builtinString_localeCompare, + }, + } + toLocaleLowerCase_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toLocaleLowerCase", + call: builtinString_toLocaleLowerCase, + }, + } + toLocaleUpperCase_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toLocaleUpperCase", + call: builtinString_toLocaleUpperCase, + }, + } + fromCharCode_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "fromCharCode", + call: builtinString_fromCharCode, + }, + } + runtime.global.StringPrototype = &_object{ + runtime: runtime, + class: "String", + objectClass: _classString, + prototype: runtime.global.ObjectPrototype, + extensible: true, + value: prototypeValueString, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: int(0), + }, + }, + "toString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toString_function, + }, + }, + "valueOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: valueOf_function, + }, + }, + "charAt": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: charAt_function, + }, + }, + "charCodeAt": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: charCodeAt_function, + }, + }, + "concat": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: concat_function, + }, + }, + "indexOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: indexOf_function, + }, + }, + "lastIndexOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: lastIndexOf_function, + }, + }, + "match": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: match_function, + }, + }, + "replace": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: replace_function, + }, + }, + "search": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: search_function, + }, + }, + "split": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: split_function, + }, + }, + "slice": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: slice_function, + }, + }, + "substring": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: substring_function, + }, + }, + "toLowerCase": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toLowerCase_function, + }, + }, + "toUpperCase": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toUpperCase_function, + }, + }, + "substr": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: substr_function, + }, + }, + "trim": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: trim_function, + }, + }, + "trimLeft": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: trimLeft_function, + }, + }, + "trimRight": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: trimRight_function, + }, + }, + "localeCompare": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: localeCompare_function, + }, + }, + "toLocaleLowerCase": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toLocaleLowerCase_function, + }, + }, + "toLocaleUpperCase": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toLocaleUpperCase_function, + }, + }, + }, + propertyOrder: []string{ + "length", + "toString", + "valueOf", + "charAt", + "charCodeAt", + "concat", + "indexOf", + "lastIndexOf", + "match", + "replace", + "search", + "split", + "slice", + "substring", + "toLowerCase", + "toUpperCase", + "substr", + "trim", + "trimLeft", + "trimRight", + "localeCompare", + "toLocaleLowerCase", + "toLocaleUpperCase", + }, + } + runtime.global.String = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "String", + call: builtinString, + construct: builtinNewString, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.StringPrototype, + }, + }, + "fromCharCode": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: fromCharCode_function, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + "fromCharCode", + }, + } + runtime.global.StringPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.String, + }, + } + } + { + toString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toString", + call: builtinBoolean_toString, + }, + } + valueOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "valueOf", + call: builtinBoolean_valueOf, + }, + } + runtime.global.BooleanPrototype = &_object{ + runtime: runtime, + class: "Boolean", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + value: prototypeValueBoolean, + property: map[string]_property{ + "toString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toString_function, + }, + }, + "valueOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: valueOf_function, + }, + }, + }, + propertyOrder: []string{ + "toString", + "valueOf", + }, + } + runtime.global.Boolean = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "Boolean", + call: builtinBoolean, + construct: builtinNewBoolean, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.BooleanPrototype, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + }, + } + runtime.global.BooleanPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Boolean, + }, + } + } + { + toString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toString", + call: builtinNumber_toString, + }, + } + valueOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "valueOf", + call: builtinNumber_valueOf, + }, + } + toFixed_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toFixed", + call: builtinNumber_toFixed, + }, + } + toExponential_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toExponential", + call: builtinNumber_toExponential, + }, + } + toPrecision_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toPrecision", + call: builtinNumber_toPrecision, + }, + } + toLocaleString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toLocaleString", + call: builtinNumber_toLocaleString, + }, + } + runtime.global.NumberPrototype = &_object{ + runtime: runtime, + class: "Number", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + value: prototypeValueNumber, + property: map[string]_property{ + "toString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toString_function, + }, + }, + "valueOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: valueOf_function, + }, + }, + "toFixed": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toFixed_function, + }, + }, + "toExponential": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toExponential_function, + }, + }, + "toPrecision": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toPrecision_function, + }, + }, + "toLocaleString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toLocaleString_function, + }, + }, + }, + propertyOrder: []string{ + "toString", + "valueOf", + "toFixed", + "toExponential", + "toPrecision", + "toLocaleString", + }, + } + runtime.global.Number = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "Number", + call: builtinNumber, + construct: builtinNewNumber, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.NumberPrototype, + }, + }, + "MAX_VALUE": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.MaxFloat64, + }, + }, + "MIN_VALUE": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.SmallestNonzeroFloat64, + }, + }, + "NaN": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.NaN(), + }, + }, + "NEGATIVE_INFINITY": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.Inf(-1), + }, + }, + "POSITIVE_INFINITY": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.Inf(+1), + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + "MAX_VALUE", + "MIN_VALUE", + "NaN", + "NEGATIVE_INFINITY", + "POSITIVE_INFINITY", + }, + } + runtime.global.NumberPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Number, + }, + } + } + { + abs_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "abs", + call: builtinMath_abs, + }, + } + acos_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "acos", + call: builtinMath_acos, + }, + } + asin_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "asin", + call: builtinMath_asin, + }, + } + atan_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "atan", + call: builtinMath_atan, + }, + } + atan2_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "atan2", + call: builtinMath_atan2, + }, + } + ceil_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "ceil", + call: builtinMath_ceil, + }, + } + cos_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "cos", + call: builtinMath_cos, + }, + } + exp_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "exp", + call: builtinMath_exp, + }, + } + floor_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "floor", + call: builtinMath_floor, + }, + } + log_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "log", + call: builtinMath_log, + }, + } + max_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "max", + call: builtinMath_max, + }, + } + min_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "min", + call: builtinMath_min, + }, + } + pow_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "pow", + call: builtinMath_pow, + }, + } + random_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "random", + call: builtinMath_random, + }, + } + round_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "round", + call: builtinMath_round, + }, + } + sin_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "sin", + call: builtinMath_sin, + }, + } + sqrt_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "sqrt", + call: builtinMath_sqrt, + }, + } + tan_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "tan", + call: builtinMath_tan, + }, + } + runtime.global.Math = &_object{ + runtime: runtime, + class: "Math", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + property: map[string]_property{ + "abs": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: abs_function, + }, + }, + "acos": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: acos_function, + }, + }, + "asin": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: asin_function, + }, + }, + "atan": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: atan_function, + }, + }, + "atan2": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: atan2_function, + }, + }, + "ceil": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: ceil_function, + }, + }, + "cos": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: cos_function, + }, + }, + "exp": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: exp_function, + }, + }, + "floor": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: floor_function, + }, + }, + "log": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: log_function, + }, + }, + "max": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: max_function, + }, + }, + "min": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: min_function, + }, + }, + "pow": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: pow_function, + }, + }, + "random": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: random_function, + }, + }, + "round": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: round_function, + }, + }, + "sin": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: sin_function, + }, + }, + "sqrt": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: sqrt_function, + }, + }, + "tan": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: tan_function, + }, + }, + "E": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.E, + }, + }, + "LN10": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.Ln10, + }, + }, + "LN2": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.Ln2, + }, + }, + "LOG2E": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.Log2E, + }, + }, + "LOG10E": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.Log10E, + }, + }, + "PI": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.Pi, + }, + }, + "SQRT1_2": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: sqrt1_2, + }, + }, + "SQRT2": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.Sqrt2, + }, + }, + }, + propertyOrder: []string{ + "abs", + "acos", + "asin", + "atan", + "atan2", + "ceil", + "cos", + "exp", + "floor", + "log", + "max", + "min", + "pow", + "random", + "round", + "sin", + "sqrt", + "tan", + "E", + "LN10", + "LN2", + "LOG2E", + "LOG10E", + "PI", + "SQRT1_2", + "SQRT2", + }, + } + } + { + toString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toString", + call: builtinDate_toString, + }, + } + toDateString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toDateString", + call: builtinDate_toDateString, + }, + } + toTimeString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toTimeString", + call: builtinDate_toTimeString, + }, + } + toUTCString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toUTCString", + call: builtinDate_toUTCString, + }, + } + toISOString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toISOString", + call: builtinDate_toISOString, + }, + } + toJSON_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toJSON", + call: builtinDate_toJSON, + }, + } + toGMTString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toGMTString", + call: builtinDate_toGMTString, + }, + } + toLocaleString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toLocaleString", + call: builtinDate_toLocaleString, + }, + } + toLocaleDateString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toLocaleDateString", + call: builtinDate_toLocaleDateString, + }, + } + toLocaleTimeString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toLocaleTimeString", + call: builtinDate_toLocaleTimeString, + }, + } + valueOf_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "valueOf", + call: builtinDate_valueOf, + }, + } + getTime_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getTime", + call: builtinDate_getTime, + }, + } + getYear_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getYear", + call: builtinDate_getYear, + }, + } + getFullYear_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getFullYear", + call: builtinDate_getFullYear, + }, + } + getUTCFullYear_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getUTCFullYear", + call: builtinDate_getUTCFullYear, + }, + } + getMonth_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getMonth", + call: builtinDate_getMonth, + }, + } + getUTCMonth_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getUTCMonth", + call: builtinDate_getUTCMonth, + }, + } + getDate_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getDate", + call: builtinDate_getDate, + }, + } + getUTCDate_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getUTCDate", + call: builtinDate_getUTCDate, + }, + } + getDay_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getDay", + call: builtinDate_getDay, + }, + } + getUTCDay_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getUTCDay", + call: builtinDate_getUTCDay, + }, + } + getHours_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getHours", + call: builtinDate_getHours, + }, + } + getUTCHours_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getUTCHours", + call: builtinDate_getUTCHours, + }, + } + getMinutes_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getMinutes", + call: builtinDate_getMinutes, + }, + } + getUTCMinutes_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getUTCMinutes", + call: builtinDate_getUTCMinutes, + }, + } + getSeconds_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getSeconds", + call: builtinDate_getSeconds, + }, + } + getUTCSeconds_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getUTCSeconds", + call: builtinDate_getUTCSeconds, + }, + } + getMilliseconds_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getMilliseconds", + call: builtinDate_getMilliseconds, + }, + } + getUTCMilliseconds_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getUTCMilliseconds", + call: builtinDate_getUTCMilliseconds, + }, + } + getTimezoneOffset_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "getTimezoneOffset", + call: builtinDate_getTimezoneOffset, + }, + } + setTime_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setTime", + call: builtinDate_setTime, + }, + } + setMilliseconds_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setMilliseconds", + call: builtinDate_setMilliseconds, + }, + } + setUTCMilliseconds_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setUTCMilliseconds", + call: builtinDate_setUTCMilliseconds, + }, + } + setSeconds_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setSeconds", + call: builtinDate_setSeconds, + }, + } + setUTCSeconds_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setUTCSeconds", + call: builtinDate_setUTCSeconds, + }, + } + setMinutes_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 3, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setMinutes", + call: builtinDate_setMinutes, + }, + } + setUTCMinutes_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 3, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setUTCMinutes", + call: builtinDate_setUTCMinutes, + }, + } + setHours_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 4, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setHours", + call: builtinDate_setHours, + }, + } + setUTCHours_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 4, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setUTCHours", + call: builtinDate_setUTCHours, + }, + } + setDate_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setDate", + call: builtinDate_setDate, + }, + } + setUTCDate_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setUTCDate", + call: builtinDate_setUTCDate, + }, + } + setMonth_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setMonth", + call: builtinDate_setMonth, + }, + } + setUTCMonth_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setUTCMonth", + call: builtinDate_setUTCMonth, + }, + } + setYear_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setYear", + call: builtinDate_setYear, + }, + } + setFullYear_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 3, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setFullYear", + call: builtinDate_setFullYear, + }, + } + setUTCFullYear_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 3, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "setUTCFullYear", + call: builtinDate_setUTCFullYear, + }, + } + parse_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "parse", + call: builtinDate_parse, + }, + } + UTC_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 7, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "UTC", + call: builtinDate_UTC, + }, + } + now_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "now", + call: builtinDate_now, + }, + } + runtime.global.DatePrototype = &_object{ + runtime: runtime, + class: "Date", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + value: prototypeValueDate, + property: map[string]_property{ + "toString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toString_function, + }, + }, + "toDateString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toDateString_function, + }, + }, + "toTimeString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toTimeString_function, + }, + }, + "toUTCString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toUTCString_function, + }, + }, + "toISOString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toISOString_function, + }, + }, + "toJSON": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toJSON_function, + }, + }, + "toGMTString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toGMTString_function, + }, + }, + "toLocaleString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toLocaleString_function, + }, + }, + "toLocaleDateString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toLocaleDateString_function, + }, + }, + "toLocaleTimeString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toLocaleTimeString_function, + }, + }, + "valueOf": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: valueOf_function, + }, + }, + "getTime": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getTime_function, + }, + }, + "getYear": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getYear_function, + }, + }, + "getFullYear": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getFullYear_function, + }, + }, + "getUTCFullYear": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getUTCFullYear_function, + }, + }, + "getMonth": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getMonth_function, + }, + }, + "getUTCMonth": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getUTCMonth_function, + }, + }, + "getDate": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getDate_function, + }, + }, + "getUTCDate": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getUTCDate_function, + }, + }, + "getDay": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getDay_function, + }, + }, + "getUTCDay": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getUTCDay_function, + }, + }, + "getHours": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getHours_function, + }, + }, + "getUTCHours": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getUTCHours_function, + }, + }, + "getMinutes": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getMinutes_function, + }, + }, + "getUTCMinutes": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getUTCMinutes_function, + }, + }, + "getSeconds": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getSeconds_function, + }, + }, + "getUTCSeconds": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getUTCSeconds_function, + }, + }, + "getMilliseconds": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getMilliseconds_function, + }, + }, + "getUTCMilliseconds": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getUTCMilliseconds_function, + }, + }, + "getTimezoneOffset": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: getTimezoneOffset_function, + }, + }, + "setTime": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setTime_function, + }, + }, + "setMilliseconds": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setMilliseconds_function, + }, + }, + "setUTCMilliseconds": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setUTCMilliseconds_function, + }, + }, + "setSeconds": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setSeconds_function, + }, + }, + "setUTCSeconds": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setUTCSeconds_function, + }, + }, + "setMinutes": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setMinutes_function, + }, + }, + "setUTCMinutes": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setUTCMinutes_function, + }, + }, + "setHours": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setHours_function, + }, + }, + "setUTCHours": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setUTCHours_function, + }, + }, + "setDate": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setDate_function, + }, + }, + "setUTCDate": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setUTCDate_function, + }, + }, + "setMonth": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setMonth_function, + }, + }, + "setUTCMonth": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setUTCMonth_function, + }, + }, + "setYear": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setYear_function, + }, + }, + "setFullYear": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setFullYear_function, + }, + }, + "setUTCFullYear": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: setUTCFullYear_function, + }, + }, + }, + propertyOrder: []string{ + "toString", + "toDateString", + "toTimeString", + "toUTCString", + "toISOString", + "toJSON", + "toGMTString", + "toLocaleString", + "toLocaleDateString", + "toLocaleTimeString", + "valueOf", + "getTime", + "getYear", + "getFullYear", + "getUTCFullYear", + "getMonth", + "getUTCMonth", + "getDate", + "getUTCDate", + "getDay", + "getUTCDay", + "getHours", + "getUTCHours", + "getMinutes", + "getUTCMinutes", + "getSeconds", + "getUTCSeconds", + "getMilliseconds", + "getUTCMilliseconds", + "getTimezoneOffset", + "setTime", + "setMilliseconds", + "setUTCMilliseconds", + "setSeconds", + "setUTCSeconds", + "setMinutes", + "setUTCMinutes", + "setHours", + "setUTCHours", + "setDate", + "setUTCDate", + "setMonth", + "setUTCMonth", + "setYear", + "setFullYear", + "setUTCFullYear", + }, + } + runtime.global.Date = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "Date", + call: builtinDate, + construct: builtinNewDate, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 7, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.DatePrototype, + }, + }, + "parse": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: parse_function, + }, + }, + "UTC": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: UTC_function, + }, + }, + "now": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: now_function, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + "parse", + "UTC", + "now", + }, + } + runtime.global.DatePrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Date, + }, + } + } + { + toString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toString", + call: builtinRegExp_toString, + }, + } + exec_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "exec", + call: builtinRegExp_exec, + }, + } + test_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "test", + call: builtinRegExp_test, + }, + } + compile_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "compile", + call: builtinRegExp_compile, + }, + } + runtime.global.RegExpPrototype = &_object{ + runtime: runtime, + class: "RegExp", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + value: prototypeValueRegExp, + property: map[string]_property{ + "toString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toString_function, + }, + }, + "exec": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: exec_function, + }, + }, + "test": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: test_function, + }, + }, + "compile": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: compile_function, + }, + }, + }, + propertyOrder: []string{ + "toString", + "exec", + "test", + "compile", + }, + } + runtime.global.RegExp = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "RegExp", + call: builtinRegExp, + construct: builtinNewRegExp, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.RegExpPrototype, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + }, + } + runtime.global.RegExpPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.RegExp, + }, + } + } + { + toString_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "toString", + call: builtinError_toString, + }, + } + runtime.global.ErrorPrototype = &_object{ + runtime: runtime, + class: "Error", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + value: nil, + property: map[string]_property{ + "toString": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: toString_function, + }, + }, + "name": _property{ + mode: 0101, + value: Value{ + kind: valueString, + value: "Error", + }, + }, + "message": _property{ + mode: 0101, + value: Value{ + kind: valueString, + value: "", + }, + }, + }, + propertyOrder: []string{ + "toString", + "name", + "message", + }, + } + runtime.global.Error = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "Error", + call: builtinError, + construct: builtinNewError, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.ErrorPrototype, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + }, + } + runtime.global.ErrorPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Error, + }, + } + } + { + runtime.global.EvalErrorPrototype = &_object{ + runtime: runtime, + class: "EvalError", + objectClass: _classObject, + prototype: runtime.global.ErrorPrototype, + extensible: true, + value: nil, + property: map[string]_property{ + "name": _property{ + mode: 0101, + value: Value{ + kind: valueString, + value: "EvalError", + }, + }, + }, + propertyOrder: []string{ + "name", + }, + } + runtime.global.EvalError = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "EvalError", + call: builtinEvalError, + construct: builtinNewEvalError, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.EvalErrorPrototype, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + }, + } + runtime.global.EvalErrorPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.EvalError, + }, + } + } + { + runtime.global.TypeErrorPrototype = &_object{ + runtime: runtime, + class: "TypeError", + objectClass: _classObject, + prototype: runtime.global.ErrorPrototype, + extensible: true, + value: nil, + property: map[string]_property{ + "name": _property{ + mode: 0101, + value: Value{ + kind: valueString, + value: "TypeError", + }, + }, + }, + propertyOrder: []string{ + "name", + }, + } + runtime.global.TypeError = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "TypeError", + call: builtinTypeError, + construct: builtinNewTypeError, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.TypeErrorPrototype, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + }, + } + runtime.global.TypeErrorPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.TypeError, + }, + } + } + { + runtime.global.RangeErrorPrototype = &_object{ + runtime: runtime, + class: "RangeError", + objectClass: _classObject, + prototype: runtime.global.ErrorPrototype, + extensible: true, + value: nil, + property: map[string]_property{ + "name": _property{ + mode: 0101, + value: Value{ + kind: valueString, + value: "RangeError", + }, + }, + }, + propertyOrder: []string{ + "name", + }, + } + runtime.global.RangeError = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "RangeError", + call: builtinRangeError, + construct: builtinNewRangeError, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.RangeErrorPrototype, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + }, + } + runtime.global.RangeErrorPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.RangeError, + }, + } + } + { + runtime.global.ReferenceErrorPrototype = &_object{ + runtime: runtime, + class: "ReferenceError", + objectClass: _classObject, + prototype: runtime.global.ErrorPrototype, + extensible: true, + value: nil, + property: map[string]_property{ + "name": _property{ + mode: 0101, + value: Value{ + kind: valueString, + value: "ReferenceError", + }, + }, + }, + propertyOrder: []string{ + "name", + }, + } + runtime.global.ReferenceError = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "ReferenceError", + call: builtinReferenceError, + construct: builtinNewReferenceError, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.ReferenceErrorPrototype, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + }, + } + runtime.global.ReferenceErrorPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.ReferenceError, + }, + } + } + { + runtime.global.SyntaxErrorPrototype = &_object{ + runtime: runtime, + class: "SyntaxError", + objectClass: _classObject, + prototype: runtime.global.ErrorPrototype, + extensible: true, + value: nil, + property: map[string]_property{ + "name": _property{ + mode: 0101, + value: Value{ + kind: valueString, + value: "SyntaxError", + }, + }, + }, + propertyOrder: []string{ + "name", + }, + } + runtime.global.SyntaxError = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "SyntaxError", + call: builtinSyntaxError, + construct: builtinNewSyntaxError, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.SyntaxErrorPrototype, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + }, + } + runtime.global.SyntaxErrorPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.SyntaxError, + }, + } + } + { + runtime.global.URIErrorPrototype = &_object{ + runtime: runtime, + class: "URIError", + objectClass: _classObject, + prototype: runtime.global.ErrorPrototype, + extensible: true, + value: nil, + property: map[string]_property{ + "name": _property{ + mode: 0101, + value: Value{ + kind: valueString, + value: "URIError", + }, + }, + }, + propertyOrder: []string{ + "name", + }, + } + runtime.global.URIError = &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + value: _nativeFunctionObject{ + name: "URIError", + call: builtinURIError, + construct: builtinNewURIError, + }, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + "prototype": _property{ + mode: 0, + value: Value{ + kind: valueObject, + value: runtime.global.URIErrorPrototype, + }, + }, + }, + propertyOrder: []string{ + "length", + "prototype", + }, + } + runtime.global.URIErrorPrototype.property["constructor"] = + _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.URIError, + }, + } + } + { + parse_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "parse", + call: builtinJSON_parse, + }, + } + stringify_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 3, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "stringify", + call: builtinJSON_stringify, + }, + } + runtime.global.JSON = &_object{ + runtime: runtime, + class: "JSON", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + property: map[string]_property{ + "parse": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: parse_function, + }, + }, + "stringify": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: stringify_function, + }, + }, + }, + propertyOrder: []string{ + "parse", + "stringify", + }, + } + } + { + eval_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "eval", + call: builtinGlobal_eval, + }, + } + parseInt_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 2, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "parseInt", + call: builtinGlobal_parseInt, + }, + } + parseFloat_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "parseFloat", + call: builtinGlobal_parseFloat, + }, + } + isNaN_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "isNaN", + call: builtinGlobal_isNaN, + }, + } + isFinite_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "isFinite", + call: builtinGlobal_isFinite, + }, + } + decodeURI_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "decodeURI", + call: builtinGlobal_decodeURI, + }, + } + decodeURIComponent_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "decodeURIComponent", + call: builtinGlobal_decodeURIComponent, + }, + } + encodeURI_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "encodeURI", + call: builtinGlobal_encodeURI, + }, + } + encodeURIComponent_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "encodeURIComponent", + call: builtinGlobal_encodeURIComponent, + }, + } + escape_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "escape", + call: builtinGlobal_escape, + }, + } + unescape_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 1, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "unescape", + call: builtinGlobal_unescape, + }, + } + runtime.globalObject.property = map[string]_property{ + "eval": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: eval_function, + }, + }, + "parseInt": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: parseInt_function, + }, + }, + "parseFloat": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: parseFloat_function, + }, + }, + "isNaN": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: isNaN_function, + }, + }, + "isFinite": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: isFinite_function, + }, + }, + "decodeURI": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: decodeURI_function, + }, + }, + "decodeURIComponent": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: decodeURIComponent_function, + }, + }, + "encodeURI": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: encodeURI_function, + }, + }, + "encodeURIComponent": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: encodeURIComponent_function, + }, + }, + "escape": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: escape_function, + }, + }, + "unescape": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: unescape_function, + }, + }, + "Object": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Object, + }, + }, + "Function": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Function, + }, + }, + "Array": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Array, + }, + }, + "String": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.String, + }, + }, + "Boolean": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Boolean, + }, + }, + "Number": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Number, + }, + }, + "Math": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Math, + }, + }, + "Date": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Date, + }, + }, + "RegExp": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.RegExp, + }, + }, + "Error": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.Error, + }, + }, + "EvalError": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.EvalError, + }, + }, + "TypeError": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.TypeError, + }, + }, + "RangeError": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.RangeError, + }, + }, + "ReferenceError": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.ReferenceError, + }, + }, + "SyntaxError": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.SyntaxError, + }, + }, + "URIError": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.URIError, + }, + }, + "JSON": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: runtime.global.JSON, + }, + }, + "undefined": _property{ + mode: 0, + value: Value{ + kind: valueUndefined, + }, + }, + "NaN": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.NaN(), + }, + }, + "Infinity": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: math.Inf(+1), + }, + }, + } + runtime.globalObject.propertyOrder = []string{ + "eval", + "parseInt", + "parseFloat", + "isNaN", + "isFinite", + "decodeURI", + "decodeURIComponent", + "encodeURI", + "encodeURIComponent", + "escape", + "unescape", + "Object", + "Function", + "Array", + "String", + "Boolean", + "Number", + "Math", + "Date", + "RegExp", + "Error", + "EvalError", + "TypeError", + "RangeError", + "ReferenceError", + "SyntaxError", + "URIError", + "JSON", + "undefined", + "NaN", + "Infinity", + } + } +} + +func newConsoleObject(runtime *_runtime) *_object { + { + log_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "log", + call: builtinConsole_log, + }, + } + debug_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "debug", + call: builtinConsole_log, + }, + } + info_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "info", + call: builtinConsole_log, + }, + } + error_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "error", + call: builtinConsole_error, + }, + } + warn_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "warn", + call: builtinConsole_error, + }, + } + dir_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "dir", + call: builtinConsole_dir, + }, + } + time_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "time", + call: builtinConsole_time, + }, + } + timeEnd_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "timeEnd", + call: builtinConsole_timeEnd, + }, + } + trace_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "trace", + call: builtinConsole_trace, + }, + } + assert_function := &_object{ + runtime: runtime, + class: "Function", + objectClass: _classObject, + prototype: runtime.global.FunctionPrototype, + extensible: true, + property: map[string]_property{ + "length": _property{ + mode: 0, + value: Value{ + kind: valueNumber, + value: 0, + }, + }, + }, + propertyOrder: []string{ + "length", + }, + value: _nativeFunctionObject{ + name: "assert", + call: builtinConsole_assert, + }, + } + return &_object{ + runtime: runtime, + class: "Object", + objectClass: _classObject, + prototype: runtime.global.ObjectPrototype, + extensible: true, + property: map[string]_property{ + "log": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: log_function, + }, + }, + "debug": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: debug_function, + }, + }, + "info": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: info_function, + }, + }, + "error": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: error_function, + }, + }, + "warn": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: warn_function, + }, + }, + "dir": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: dir_function, + }, + }, + "time": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: time_function, + }, + }, + "timeEnd": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: timeEnd_function, + }, + }, + "trace": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: trace_function, + }, + }, + "assert": _property{ + mode: 0101, + value: Value{ + kind: valueObject, + value: assert_function, + }, + }, + }, + propertyOrder: []string{ + "log", + "debug", + "info", + "error", + "warn", + "dir", + "time", + "timeEnd", + "trace", + "assert", + }, + } + } +} + +func toValue_int(value int) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_int8(value int8) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_int16(value int16) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_int32(value int32) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_int64(value int64) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_uint(value uint) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_uint8(value uint8) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_uint16(value uint16) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_uint32(value uint32) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_uint64(value uint64) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_float32(value float32) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_float64(value float64) Value { + return Value{ + kind: valueNumber, + value: value, + } +} + +func toValue_string(value string) Value { + return Value{ + kind: valueString, + value: value, + } +} + +func toValue_string16(value []uint16) Value { + return Value{ + kind: valueString, + value: value, + } +} + +func toValue_bool(value bool) Value { + return Value{ + kind: valueBoolean, + value: value, + } +} + +func toValue_object(value *_object) Value { + return Value{ + kind: valueObject, + value: value, + } +} diff --git a/vendor/github.com/robertkrimen/otto/object.go b/vendor/github.com/robertkrimen/otto/object.go new file mode 100644 index 0000000..849812c --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/object.go @@ -0,0 +1,156 @@ +package otto + +type _object struct { + runtime *_runtime + + class string + objectClass *_objectClass + value interface{} + + prototype *_object + extensible bool + + property map[string]_property + propertyOrder []string +} + +func newObject(runtime *_runtime, class string) *_object { + self := &_object{ + runtime: runtime, + class: class, + objectClass: _classObject, + property: make(map[string]_property), + extensible: true, + } + return self +} + +// 8.12 + +// 8.12.1 +func (self *_object) getOwnProperty(name string) *_property { + return self.objectClass.getOwnProperty(self, name) +} + +// 8.12.2 +func (self *_object) getProperty(name string) *_property { + return self.objectClass.getProperty(self, name) +} + +// 8.12.3 +func (self *_object) get(name string) Value { + return self.objectClass.get(self, name) +} + +// 8.12.4 +func (self *_object) canPut(name string) bool { + return self.objectClass.canPut(self, name) +} + +// 8.12.5 +func (self *_object) put(name string, value Value, throw bool) { + self.objectClass.put(self, name, value, throw) +} + +// 8.12.6 +func (self *_object) hasProperty(name string) bool { + return self.objectClass.hasProperty(self, name) +} + +func (self *_object) hasOwnProperty(name string) bool { + return self.objectClass.hasOwnProperty(self, name) +} + +type _defaultValueHint int + +const ( + defaultValueNoHint _defaultValueHint = iota + defaultValueHintString + defaultValueHintNumber +) + +// 8.12.8 +func (self *_object) DefaultValue(hint _defaultValueHint) Value { + if hint == defaultValueNoHint { + if self.class == "Date" { + // Date exception + hint = defaultValueHintString + } else { + hint = defaultValueHintNumber + } + } + methodSequence := []string{"valueOf", "toString"} + if hint == defaultValueHintString { + methodSequence = []string{"toString", "valueOf"} + } + for _, methodName := range methodSequence { + method := self.get(methodName) + // FIXME This is redundant... + if method.isCallable() { + result := method._object().call(toValue_object(self), nil, false, nativeFrame) + if result.IsPrimitive() { + return result + } + } + } + + panic(self.runtime.panicTypeError()) +} + +func (self *_object) String() string { + return self.DefaultValue(defaultValueHintString).string() +} + +func (self *_object) defineProperty(name string, value Value, mode _propertyMode, throw bool) bool { + return self.defineOwnProperty(name, _property{value, mode}, throw) +} + +// 8.12.9 +func (self *_object) defineOwnProperty(name string, descriptor _property, throw bool) bool { + return self.objectClass.defineOwnProperty(self, name, descriptor, throw) +} + +func (self *_object) delete(name string, throw bool) bool { + return self.objectClass.delete(self, name, throw) +} + +func (self *_object) enumerate(all bool, each func(string) bool) { + self.objectClass.enumerate(self, all, each) +} + +func (self *_object) _exists(name string) bool { + _, exists := self.property[name] + return exists +} + +func (self *_object) _read(name string) (_property, bool) { + property, exists := self.property[name] + return property, exists +} + +func (self *_object) _write(name string, value interface{}, mode _propertyMode) { + if value == nil { + value = Value{} + } + _, exists := self.property[name] + self.property[name] = _property{value, mode} + if !exists { + self.propertyOrder = append(self.propertyOrder, name) + } +} + +func (self *_object) _delete(name string) { + _, exists := self.property[name] + delete(self.property, name) + if exists { + for index, property := range self.propertyOrder { + if name == property { + if index == len(self.propertyOrder)-1 { + self.propertyOrder = self.propertyOrder[:index] + } else { + self.propertyOrder = append(self.propertyOrder[:index], self.propertyOrder[index+1:]...) + } + } + } + } +} diff --git a/vendor/github.com/robertkrimen/otto/object_class.go b/vendor/github.com/robertkrimen/otto/object_class.go new file mode 100644 index 0000000..d18b9ce --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/object_class.go @@ -0,0 +1,493 @@ +package otto + +import ( + "encoding/json" +) + +type _objectClass struct { + getOwnProperty func(*_object, string) *_property + getProperty func(*_object, string) *_property + get func(*_object, string) Value + canPut func(*_object, string) bool + put func(*_object, string, Value, bool) + hasProperty func(*_object, string) bool + hasOwnProperty func(*_object, string) bool + defineOwnProperty func(*_object, string, _property, bool) bool + delete func(*_object, string, bool) bool + enumerate func(*_object, bool, func(string) bool) + clone func(*_object, *_object, *_clone) *_object + marshalJSON func(*_object) json.Marshaler +} + +func objectEnumerate(self *_object, all bool, each func(string) bool) { + for _, name := range self.propertyOrder { + if all || self.property[name].enumerable() { + if !each(name) { + return + } + } + } +} + +var ( + _classObject, + _classArray, + _classString, + _classArguments, + _classGoStruct, + _classGoMap, + _classGoArray, + _classGoSlice, + _ *_objectClass +) + +func init() { + _classObject = &_objectClass{ + objectGetOwnProperty, + objectGetProperty, + objectGet, + objectCanPut, + objectPut, + objectHasProperty, + objectHasOwnProperty, + objectDefineOwnProperty, + objectDelete, + objectEnumerate, + objectClone, + nil, + } + + _classArray = &_objectClass{ + objectGetOwnProperty, + objectGetProperty, + objectGet, + objectCanPut, + objectPut, + objectHasProperty, + objectHasOwnProperty, + arrayDefineOwnProperty, + objectDelete, + objectEnumerate, + objectClone, + nil, + } + + _classString = &_objectClass{ + stringGetOwnProperty, + objectGetProperty, + objectGet, + objectCanPut, + objectPut, + objectHasProperty, + objectHasOwnProperty, + objectDefineOwnProperty, + objectDelete, + stringEnumerate, + objectClone, + nil, + } + + _classArguments = &_objectClass{ + argumentsGetOwnProperty, + objectGetProperty, + argumentsGet, + objectCanPut, + objectPut, + objectHasProperty, + objectHasOwnProperty, + argumentsDefineOwnProperty, + argumentsDelete, + objectEnumerate, + objectClone, + nil, + } + + _classGoStruct = &_objectClass{ + goStructGetOwnProperty, + objectGetProperty, + objectGet, + goStructCanPut, + goStructPut, + objectHasProperty, + objectHasOwnProperty, + objectDefineOwnProperty, + objectDelete, + goStructEnumerate, + objectClone, + goStructMarshalJSON, + } + + _classGoMap = &_objectClass{ + goMapGetOwnProperty, + objectGetProperty, + objectGet, + objectCanPut, + objectPut, + objectHasProperty, + objectHasOwnProperty, + goMapDefineOwnProperty, + goMapDelete, + goMapEnumerate, + objectClone, + nil, + } + + _classGoArray = &_objectClass{ + goArrayGetOwnProperty, + objectGetProperty, + objectGet, + objectCanPut, + objectPut, + objectHasProperty, + objectHasOwnProperty, + goArrayDefineOwnProperty, + goArrayDelete, + goArrayEnumerate, + objectClone, + nil, + } + + _classGoSlice = &_objectClass{ + goSliceGetOwnProperty, + objectGetProperty, + objectGet, + objectCanPut, + objectPut, + objectHasProperty, + objectHasOwnProperty, + goSliceDefineOwnProperty, + goSliceDelete, + goSliceEnumerate, + objectClone, + nil, + } +} + +// Allons-y + +// 8.12.1 +func objectGetOwnProperty(self *_object, name string) *_property { + // Return a _copy_ of the property + property, exists := self._read(name) + if !exists { + return nil + } + return &property +} + +// 8.12.2 +func objectGetProperty(self *_object, name string) *_property { + property := self.getOwnProperty(name) + if property != nil { + return property + } + if self.prototype != nil { + return self.prototype.getProperty(name) + } + return nil +} + +// 8.12.3 +func objectGet(self *_object, name string) Value { + property := self.getProperty(name) + if property != nil { + return property.get(self) + } + return Value{} +} + +// 8.12.4 +func objectCanPut(self *_object, name string) bool { + canPut, _, _ := _objectCanPut(self, name) + return canPut +} + +func _objectCanPut(self *_object, name string) (canPut bool, property *_property, setter *_object) { + property = self.getOwnProperty(name) + if property != nil { + switch propertyValue := property.value.(type) { + case Value: + canPut = property.writable() + return + case _propertyGetSet: + setter = propertyValue[1] + canPut = setter != nil + return + default: + panic(self.runtime.panicTypeError()) + } + } + + if self.prototype == nil { + return self.extensible, nil, nil + } + + property = self.prototype.getProperty(name) + if property == nil { + return self.extensible, nil, nil + } + + switch propertyValue := property.value.(type) { + case Value: + if !self.extensible { + return false, nil, nil + } + return property.writable(), nil, nil + case _propertyGetSet: + setter = propertyValue[1] + canPut = setter != nil + return + default: + panic(self.runtime.panicTypeError()) + } +} + +// 8.12.5 +func objectPut(self *_object, name string, value Value, throw bool) { + + if true { + // Shortcut... + // + // So, right now, every class is using objectCanPut and every class + // is using objectPut. + // + // If that were to no longer be the case, we would have to have + // something to detect that here, so that we do not use an + // incompatible canPut routine + canPut, property, setter := _objectCanPut(self, name) + if !canPut { + self.runtime.typeErrorResult(throw) + } else if setter != nil { + setter.call(toValue(self), []Value{value}, false, nativeFrame) + } else if property != nil { + property.value = value + self.defineOwnProperty(name, *property, throw) + } else { + self.defineProperty(name, value, 0111, throw) + } + return + } + + // The long way... + // + // Right now, code should never get here, see above + if !self.canPut(name) { + self.runtime.typeErrorResult(throw) + return + } + + property := self.getOwnProperty(name) + if property == nil { + property = self.getProperty(name) + if property != nil { + if getSet, isAccessor := property.value.(_propertyGetSet); isAccessor { + getSet[1].call(toValue(self), []Value{value}, false, nativeFrame) + return + } + } + self.defineProperty(name, value, 0111, throw) + } else { + switch propertyValue := property.value.(type) { + case Value: + property.value = value + self.defineOwnProperty(name, *property, throw) + case _propertyGetSet: + if propertyValue[1] != nil { + propertyValue[1].call(toValue(self), []Value{value}, false, nativeFrame) + return + } + if throw { + panic(self.runtime.panicTypeError()) + } + default: + panic(self.runtime.panicTypeError()) + } + } +} + +// 8.12.6 +func objectHasProperty(self *_object, name string) bool { + return self.getProperty(name) != nil +} + +func objectHasOwnProperty(self *_object, name string) bool { + return self.getOwnProperty(name) != nil +} + +// 8.12.9 +func objectDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { + property, exists := self._read(name) + { + if !exists { + if !self.extensible { + goto Reject + } + if newGetSet, isAccessor := descriptor.value.(_propertyGetSet); isAccessor { + if newGetSet[0] == &_nilGetSetObject { + newGetSet[0] = nil + } + if newGetSet[1] == &_nilGetSetObject { + newGetSet[1] = nil + } + descriptor.value = newGetSet + } + self._write(name, descriptor.value, descriptor.mode) + return true + } + if descriptor.isEmpty() { + return true + } + + // TODO Per 8.12.9.6 - We should shortcut here (returning true) if + // the current and new (define) properties are the same + + configurable := property.configurable() + if !configurable { + if descriptor.configurable() { + goto Reject + } + // Test that, if enumerable is set on the property descriptor, then it should + // be the same as the existing property + if descriptor.enumerateSet() && descriptor.enumerable() != property.enumerable() { + goto Reject + } + } + value, isDataDescriptor := property.value.(Value) + getSet, _ := property.value.(_propertyGetSet) + if descriptor.isGenericDescriptor() { + // GenericDescriptor + } else if isDataDescriptor != descriptor.isDataDescriptor() { + // DataDescriptor <=> AccessorDescriptor + if !configurable { + goto Reject + } + } else if isDataDescriptor && descriptor.isDataDescriptor() { + // DataDescriptor <=> DataDescriptor + if !configurable { + if !property.writable() && descriptor.writable() { + goto Reject + } + if !property.writable() { + if descriptor.value != nil && !sameValue(value, descriptor.value.(Value)) { + goto Reject + } + } + } + } else { + // AccessorDescriptor <=> AccessorDescriptor + newGetSet, _ := descriptor.value.(_propertyGetSet) + presentGet, presentSet := true, true + if newGetSet[0] == &_nilGetSetObject { + // Present, but nil + newGetSet[0] = nil + } else if newGetSet[0] == nil { + // Missing, not even nil + newGetSet[0] = getSet[0] + presentGet = false + } + if newGetSet[1] == &_nilGetSetObject { + // Present, but nil + newGetSet[1] = nil + } else if newGetSet[1] == nil { + // Missing, not even nil + newGetSet[1] = getSet[1] + presentSet = false + } + if !configurable { + if (presentGet && (getSet[0] != newGetSet[0])) || (presentSet && (getSet[1] != newGetSet[1])) { + goto Reject + } + } + descriptor.value = newGetSet + } + { + // This section will preserve attributes of + // the original property, if necessary + value1 := descriptor.value + if value1 == nil { + value1 = property.value + } else if newGetSet, isAccessor := descriptor.value.(_propertyGetSet); isAccessor { + if newGetSet[0] == &_nilGetSetObject { + newGetSet[0] = nil + } + if newGetSet[1] == &_nilGetSetObject { + newGetSet[1] = nil + } + value1 = newGetSet + } + mode1 := descriptor.mode + if mode1&0222 != 0 { + // TODO Factor this out into somewhere testable + // (Maybe put into switch ...) + mode0 := property.mode + if mode1&0200 != 0 { + if descriptor.isDataDescriptor() { + mode1 &= ^0200 // Turn off "writable" missing + mode1 |= (mode0 & 0100) + } + } + if mode1&020 != 0 { + mode1 |= (mode0 & 010) + } + if mode1&02 != 0 { + mode1 |= (mode0 & 01) + } + mode1 &= 0311 // 0311 to preserve the non-setting on "writable" + } + self._write(name, value1, mode1) + } + return true + } +Reject: + if throw { + panic(self.runtime.panicTypeError()) + } + return false +} + +func objectDelete(self *_object, name string, throw bool) bool { + property_ := self.getOwnProperty(name) + if property_ == nil { + return true + } + if property_.configurable() { + self._delete(name) + return true + } + return self.runtime.typeErrorResult(throw) +} + +func objectClone(in *_object, out *_object, clone *_clone) *_object { + *out = *in + + out.runtime = clone.runtime + if out.prototype != nil { + out.prototype = clone.object(in.prototype) + } + out.property = make(map[string]_property, len(in.property)) + out.propertyOrder = make([]string, len(in.propertyOrder)) + copy(out.propertyOrder, in.propertyOrder) + for index, property := range in.property { + out.property[index] = clone.property(property) + } + + switch value := in.value.(type) { + case _nativeFunctionObject: + out.value = value + case _bindFunctionObject: + out.value = _bindFunctionObject{ + target: clone.object(value.target), + this: clone.value(value.this), + argumentList: clone.valueArray(value.argumentList), + } + case _nodeFunctionObject: + out.value = _nodeFunctionObject{ + node: value.node, + stash: clone.stash(value.stash), + } + case _argumentsObject: + out.value = value.clone(clone) + } + + return out +} diff --git a/vendor/github.com/robertkrimen/otto/otto.go b/vendor/github.com/robertkrimen/otto/otto.go new file mode 100644 index 0000000..9de3e08 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/otto.go @@ -0,0 +1,578 @@ +/* +Package otto is a JavaScript parser and interpreter written natively in Go. + +http://godoc.org/github.com/robertkrimen/otto + + import ( + "github.com/robertkrimen/otto" + ) + +Run something in the VM + + vm := otto.New() + vm.Run(` + abc = 2 + 2; + console.log("The value of abc is " + abc); // 4 + `) + +Get a value out of the VM + + value, err := vm.Get("abc") + value, _ := value.ToInteger() + } + +Set a number + + vm.Set("def", 11) + vm.Run(` + console.log("The value of def is " + def); + // The value of def is 11 + `) + +Set a string + + vm.Set("xyzzy", "Nothing happens.") + vm.Run(` + console.log(xyzzy.length); // 16 + `) + +Get the value of an expression + + value, _ = vm.Run("xyzzy.length") + { + // value is an int64 with a value of 16 + value, _ := value.ToInteger() + } + +An error happens + + value, err = vm.Run("abcdefghijlmnopqrstuvwxyz.length") + if err != nil { + // err = ReferenceError: abcdefghijlmnopqrstuvwxyz is not defined + // If there is an error, then value.IsUndefined() is true + ... + } + +Set a Go function + + vm.Set("sayHello", func(call otto.FunctionCall) otto.Value { + fmt.Printf("Hello, %s.\n", call.Argument(0).String()) + return otto.Value{} + }) + +Set a Go function that returns something useful + + vm.Set("twoPlus", func(call otto.FunctionCall) otto.Value { + right, _ := call.Argument(0).ToInteger() + result, _ := vm.ToValue(2 + right) + return result + }) + +Use the functions in JavaScript + + result, _ = vm.Run(` + sayHello("Xyzzy"); // Hello, Xyzzy. + sayHello(); // Hello, undefined + + result = twoPlus(2.0); // 4 + `) + +Parser + +A separate parser is available in the parser package if you're just interested in building an AST. + +http://godoc.org/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) + +otto + +You can run (Go) JavaScript from the commandline with: http://github.com/robertkrimen/otto/tree/master/otto + + $ go get -v github.com/robertkrimen/otto/otto + +Run JavaScript by entering some source on stdin or by giving otto a filename: + + $ otto example.js + +underscore + +Optionally include the JavaScript utility-belt library, underscore, with this import: + + import ( + "github.com/robertkrimen/otto" + _ "github.com/robertkrimen/otto/underscore" + ) + + // Now every otto runtime will come loaded with underscore + +For more information: http://github.com/robertkrimen/otto/tree/master/underscore + +Caveat Emptor + +The following are some limitations with otto: + + * "use strict" will parse, but does nothing. + * The regular expression engine (re2/regexp) is not fully compatible with the ECMA5 specification. + +Regular Expression Incompatibility + +Go translates JavaScript-style regular expressions into something that is "regexp" compatible via `parser.TransformRegExp`. +Unfortunately, RegExp requires backtracking for some patterns, and backtracking is not supported by the standard Go engine: https://code.google.com/p/re2/wiki/Syntax + +Therefore, the following syntax is incompatible: + + (?=) // Lookahead (positive), currently a parsing error + (?!) // Lookahead (backhead), currently a parsing error + \1 // Backreference (\1, \2, \3, ...), currently a parsing error + +A brief discussion of these limitations: "Regexp (?!re)" https://groups.google.com/forum/?fromgroups=#%21topic/golang-nuts/7qgSDWPIh_E + +More information about re2: https://code.google.com/p/re2/ + +In addition to the above, 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. + +Halting Problem + +If you want to stop long running executions (like third-party code), you can use the interrupt channel to do this: + + package main + + import ( + "errors" + "fmt" + "os" + "time" + + "github.com/robertkrimen/otto" + ) + + var halt = errors.New("Stahp") + + func main() { + runUnsafe(`var abc = [];`) + runUnsafe(` + while (true) { + // Loop forever + }`) + } + + func runUnsafe(unsafe string) { + start := time.Now() + defer func() { + duration := time.Since(start) + if caught := recover(); caught != nil { + if caught == halt { + fmt.Fprintf(os.Stderr, "Some code took to long! Stopping after: %v\n", duration) + return + } + panic(caught) // Something else happened, repanic! + } + fmt.Fprintf(os.Stderr, "Ran code successfully: %v\n", duration) + }() + + vm := otto.New() + 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) + } + +Where is setTimeout/setInterval? + +These timing functions are not actually part of the ECMA-262 specification. Typically, they belong to the `windows` object (in the browser). +It would not be difficult to provide something like these via Go, but you probably want to wrap otto in an event loop in that case. + +For an example of how this could be done in Go with otto, see natto: + +http://github.com/robertkrimen/natto + +Here is some more discussion of the issue: + +* http://book.mixu.net/node/ch2.html + +* http://en.wikipedia.org/wiki/Reentrancy_%28computing%29 + +* http://aaroncrane.co.uk/2009/02/perl_safe_signals/ + +*/ +package otto + +import ( + "fmt" + "strings" + + "github.com/robertkrimen/otto/registry" +) + +// Otto is the representation of the JavaScript runtime. Each instance of Otto has a self-contained namespace. +type Otto struct { + // Interrupt is a channel for interrupting the runtime. You can use this to halt a long running execution, for example. + // See "Halting Problem" for more information. + Interrupt chan func() + runtime *_runtime +} + +// New will allocate a new JavaScript runtime +func New() *Otto { + self := &Otto{ + runtime: newContext(), + } + self.runtime.otto = self + self.Set("console", self.runtime.newConsole()) + + registry.Apply(func(entry registry.Entry) { + self.Run(entry.Source()) + }) + + return self +} + +func (otto *Otto) clone() *Otto { + self := &Otto{ + runtime: otto.runtime.clone(), + } + self.runtime.otto = self + return self +} + +// Run will allocate a new JavaScript runtime, run the given source +// on the allocated runtime, and return the runtime, resulting value, and +// error (if any). +// +// src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST always be in UTF-8. +// +// src may also be a Script. +// +// src may also be a Program, but if the AST has been modified, then runtime behavior is undefined. +// +func Run(src interface{}) (*Otto, Value, error) { + otto := New() + value, err := otto.Run(src) // This already does safety checking + return otto, value, err +} + +// Run will run the given source (parsing it first if necessary), returning the resulting value and error (if any) +// +// src may be a string, a byte slice, a bytes.Buffer, or an io.Reader, but it MUST always be in UTF-8. +// +// If the runtime is unable to parse source, then this function will return undefined and the parse error (nothing +// will be evaluated in this case). +// +// src may also be a Script. +// +// src may also be a Program, but if the AST has been modified, then runtime behavior is undefined. +// +func (self Otto) Run(src interface{}) (Value, error) { + value, err := self.runtime.cmpl_run(src) + if !value.safe() { + value = Value{} + } + return value, err +} + +// Get the value of the top-level binding of the given name. +// +// If there is an error (like the binding does not exist), then the value +// will be undefined. +func (self Otto) Get(name string) (Value, error) { + value := Value{} + err := catchPanic(func() { + value = self.getValue(name) + }) + if !value.safe() { + value = Value{} + } + return value, err +} + +func (self Otto) getValue(name string) Value { + return self.runtime.globalStash.getBinding(name, false) +} + +// Set the top-level binding of the given name to the given value. +// +// Set will automatically apply ToValue to the given value in order +// to convert it to a JavaScript value (type Value). +// +// If there is an error (like the binding is read-only, or the ToValue conversion +// fails), then an error is returned. +// +// If the top-level binding does not exist, it will be created. +func (self Otto) Set(name string, value interface{}) error { + { + value, err := self.ToValue(value) + if err != nil { + return err + } + err = catchPanic(func() { + self.setValue(name, value) + }) + return err + } +} + +func (self Otto) setValue(name string, value Value) { + self.runtime.globalStash.setValue(name, value, false) +} + +// Call the given JavaScript with a given this and arguments. +// +// If this is nil, then some special handling takes place to determine the proper +// this value, falling back to a "standard" invocation if necessary (where this is +// undefined). +// +// If source begins with "new " (A lowercase new followed by a space), then +// Call will invoke the function constructor rather than performing a function call. +// In this case, the this argument has no effect. +// +// // value is a String object +// value, _ := vm.Call("Object", nil, "Hello, World.") +// +// // Likewise... +// value, _ := vm.Call("new Object", nil, "Hello, World.") +// +// // This will perform a concat on the given array and return the result +// // value is [ 1, 2, 3, undefined, 4, 5, 6, 7, "abc" ] +// value, _ := vm.Call(`[ 1, 2, 3, undefined, 4 ].concat`, nil, 5, 6, 7, "abc") +// +func (self Otto) Call(source string, this interface{}, argumentList ...interface{}) (Value, error) { + + thisValue := Value{} + + construct := false + if strings.HasPrefix(source, "new ") { + source = source[4:] + construct = true + } + + // FIXME enterGlobalScope + self.runtime.enterGlobalScope() + defer func() { + self.runtime.leaveScope() + }() + + if !construct && this == nil { + program, err := self.runtime.cmpl_parse("", source+"()") + if err == nil { + if node, ok := program.body[0].(*_nodeExpressionStatement); ok { + if node, ok := node.expression.(*_nodeCallExpression); ok { + var value Value + err := catchPanic(func() { + value = self.runtime.cmpl_evaluate_nodeCallExpression(node, argumentList) + }) + if err != nil { + return Value{}, err + } + return value, nil + } + } + } + } else { + value, err := self.ToValue(this) + if err != nil { + return Value{}, err + } + thisValue = value + } + + { + this := thisValue + + fn, err := self.Run(source) + if err != nil { + return Value{}, err + } + + if construct { + result, err := fn.constructSafe(self.runtime, this, argumentList...) + if err != nil { + return Value{}, err + } + return result, nil + } + + result, err := fn.Call(this, argumentList...) + if err != nil { + return Value{}, err + } + return result, nil + } +} + +// Object will run the given source and return the result as an object. +// +// For example, accessing an existing object: +// +// object, _ := vm.Object(`Number`) +// +// Or, creating a new object: +// +// object, _ := vm.Object(`({ xyzzy: "Nothing happens." })`) +// +// Or, creating and assigning an object: +// +// object, _ := vm.Object(`xyzzy = {}`) +// object.Set("volume", 11) +// +// If there is an error (like the source does not result in an object), then +// nil and an error is returned. +func (self Otto) Object(source string) (*Object, error) { + value, err := self.runtime.cmpl_run(source) + if err != nil { + return nil, err + } + if value.IsObject() { + return value.Object(), nil + } + return nil, fmt.Errorf("value is not an object") +} + +// ToValue will convert an interface{} value to a value digestible by otto/JavaScript. +func (self Otto) ToValue(value interface{}) (Value, error) { + return self.runtime.safeToValue(value) +} + +// Copy will create a copy/clone of the runtime. +// +// Copy is useful for saving some time when creating many similar runtimes. +// +// 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 (in *Otto) Copy() *Otto { + out := &Otto{ + runtime: in.runtime.clone(), + } + out.runtime.otto = out + return out +} + +// Object{} + +// Object is the representation of a JavaScript object. +type Object struct { + object *_object + value Value +} + +func _newObject(object *_object, value Value) *Object { + // value MUST contain object! + return &Object{ + object: object, + value: value, + } +} + +// Call a method on the object. +// +// It is essentially equivalent to: +// +// var method, _ := object.Get(name) +// method.Call(object, argumentList...) +// +// An undefined value and an error will result if: +// +// 1. There is an error during conversion of the argument list +// 2. The property is not actually a function +// 3. An (uncaught) exception is thrown +// +func (self Object) Call(name string, argumentList ...interface{}) (Value, error) { + // TODO: Insert an example using JavaScript below... + // e.g., Object("JSON").Call("stringify", ...) + + function, err := self.Get(name) + if err != nil { + return Value{}, err + } + return function.Call(self.Value(), argumentList...) +} + +// Value will return self as a value. +func (self Object) Value() Value { + return self.value +} + +// Get the value of the property with the given name. +func (self Object) Get(name string) (Value, error) { + value := Value{} + err := catchPanic(func() { + value = self.object.get(name) + }) + if !value.safe() { + value = Value{} + } + return value, err +} + +// Set the property of the given name to the given value. +// +// An error will result if the setting the property triggers an exception (i.e. read-only), +// or there is an error during conversion of the given value. +func (self Object) Set(name string, value interface{}) error { + { + value, err := self.object.runtime.safeToValue(value) + if err != nil { + return err + } + err = catchPanic(func() { + self.object.put(name, value, true) + }) + return err + } +} + +// Get the keys for the object +// +// Equivalent to calling Object.keys on the object +func (self Object) Keys() []string { + var keys []string + self.object.enumerate(false, func(name string) bool { + keys = append(keys, name) + return true + }) + return keys +} + +// Class will return the class string of the object. +// +// The return value will (generally) be one of: +// +// Object +// Function +// Array +// String +// Number +// Boolean +// Date +// RegExp +// +func (self Object) Class() string { + return self.object.class +} diff --git a/vendor/github.com/robertkrimen/otto/otto_.go b/vendor/github.com/robertkrimen/otto/otto_.go new file mode 100644 index 0000000..e053b54 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/otto_.go @@ -0,0 +1,178 @@ +package otto + +import ( + "fmt" + "regexp" + runtime_ "runtime" + "strconv" + "strings" +) + +var isIdentifier_Regexp *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z\$][a-zA-Z0-9\$]*$`) + +func isIdentifier(string_ string) bool { + return isIdentifier_Regexp.MatchString(string_) +} + +func (self *_runtime) toValueArray(arguments ...interface{}) []Value { + length := len(arguments) + if length == 1 { + if valueArray, ok := arguments[0].([]Value); ok { + return valueArray + } + return []Value{toValue(arguments[0])} + } + + valueArray := make([]Value, length) + for index, value := range arguments { + valueArray[index] = toValue(value) + } + + return valueArray +} + +func stringToArrayIndex(name string) int64 { + index, err := strconv.ParseInt(name, 10, 64) + if err != nil { + return -1 + } + if index < 0 { + return -1 + } + if index >= maxUint32 { + // The value 2^32 (or above) is not a valid index because + // you cannot store a uint32 length for an index of uint32 + return -1 + } + return index +} + +func isUint32(value int64) bool { + return value >= 0 && value <= maxUint32 +} + +func arrayIndexToString(index int64) string { + return strconv.FormatInt(index, 10) +} + +func valueOfArrayIndex(array []Value, index int) Value { + value, _ := getValueOfArrayIndex(array, index) + return value +} + +func getValueOfArrayIndex(array []Value, index int) (Value, bool) { + if index >= 0 && index < len(array) { + value := array[index] + if !value.isEmpty() { + return value, true + } + } + return Value{}, false +} + +// A range index can be anything from 0 up to length. It is NOT safe to use as an index +// to an array, but is useful for slicing and in some ECMA algorithms. +func valueToRangeIndex(indexValue Value, length int64, negativeIsZero bool) int64 { + index := indexValue.number().int64 + if negativeIsZero { + if index < 0 { + index = 0 + } + // minimum(index, length) + if index >= length { + index = length + } + return index + } + + if index < 0 { + index += length + if index < 0 { + index = 0 + } + } else { + if index > length { + index = length + } + } + return index +} + +func rangeStartEnd(array []Value, size int64, negativeIsZero bool) (start, end int64) { + start = valueToRangeIndex(valueOfArrayIndex(array, 0), size, negativeIsZero) + if len(array) == 1 { + // If there is only the start argument, then end = size + end = size + return + } + + // Assuming the argument is undefined... + end = size + endValue := valueOfArrayIndex(array, 1) + if !endValue.IsUndefined() { + // Which it is not, so get the value as an array index + end = valueToRangeIndex(endValue, size, negativeIsZero) + } + return +} + +func rangeStartLength(source []Value, size int64) (start, length int64) { + start = valueToRangeIndex(valueOfArrayIndex(source, 0), size, false) + + // Assume the second argument is missing or undefined + length = int64(size) + if len(source) == 1 { + // If there is only the start argument, then length = size + return + } + + lengthValue := valueOfArrayIndex(source, 1) + if !lengthValue.IsUndefined() { + // Which it is not, so get the value as an array index + length = lengthValue.number().int64 + } + return +} + +func boolFields(input string) (result map[string]bool) { + result = map[string]bool{} + for _, word := range strings.Fields(input) { + result[word] = true + } + return result +} + +func hereBeDragons(arguments ...interface{}) string { + pc, _, _, _ := runtime_.Caller(1) + name := runtime_.FuncForPC(pc).Name() + message := fmt.Sprintf("Here be dragons -- %s", name) + if len(arguments) > 0 { + message += ": " + argument0 := fmt.Sprintf("%s", arguments[0]) + if len(arguments) == 1 { + message += argument0 + } else { + message += fmt.Sprintf(argument0, arguments[1:]...) + } + } else { + message += "." + } + return message +} + +func throwHereBeDragons(arguments ...interface{}) { + panic(hereBeDragons(arguments...)) +} + +func eachPair(list []interface{}, fn func(_0, _1 interface{})) { + for len(list) > 0 { + var _0, _1 interface{} + _0 = list[0] + list = list[1:] // Pop off first + if len(list) > 0 { + _1 = list[0] + list = list[1:] // Pop off second + } + fn(_0, _1) + } +} diff --git a/vendor/github.com/robertkrimen/otto/parser/Makefile b/vendor/github.com/robertkrimen/otto/parser/Makefile new file mode 100644 index 0000000..766fd4d --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/parser/Makefile @@ -0,0 +1,4 @@ +.PHONY: test + +test: + go test diff --git a/vendor/github.com/robertkrimen/otto/parser/README.markdown b/vendor/github.com/robertkrimen/otto/parser/README.markdown new file mode 100644 index 0000000..c3cae5b --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/parser/README.markdown @@ -0,0 +1,190 @@ +# 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 diff --git a/vendor/github.com/robertkrimen/otto/parser/dbg.go b/vendor/github.com/robertkrimen/otto/parser/dbg.go new file mode 100644 index 0000000..3c5f2f6 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/parser/dbg.go @@ -0,0 +1,9 @@ +// This file was AUTOMATICALLY GENERATED by dbg-import (smuggol) for github.com/robertkrimen/dbg + +package parser + +import ( + Dbg "github.com/robertkrimen/otto/dbg" +) + +var dbg, dbgf = Dbg.New() diff --git a/vendor/github.com/robertkrimen/otto/parser/error.go b/vendor/github.com/robertkrimen/otto/parser/error.go new file mode 100644 index 0000000..e0f74a5 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/parser/error.go @@ -0,0 +1,175 @@ +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 +} + +// FIXME 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 +} diff --git a/vendor/github.com/robertkrimen/otto/parser/expression.go b/vendor/github.com/robertkrimen/otto/parser/expression.go new file mode 100644 index 0000000..dc397b5 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/parser/expression.go @@ -0,0 +1,815 @@ +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 +} diff --git a/vendor/github.com/robertkrimen/otto/parser/lexer.go b/vendor/github.com/robertkrimen/otto/parser/lexer.go new file mode 100644 index 0000000..bc3e74f --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/parser/lexer.go @@ -0,0 +1,819 @@ +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:] // \ + + } else { + str = str[2:] // \ + 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] +} diff --git a/vendor/github.com/robertkrimen/otto/parser/parser.go b/vendor/github.com/robertkrimen/otto/parser/parser.go new file mode 100644 index 0000000..1536344 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/parser/parser.go @@ -0,0 +1,273 @@ +/* +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 + + file *file.File +} + +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, + file: file.NewFile(filename, src, 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 +} diff --git a/vendor/github.com/robertkrimen/otto/parser/regexp.go b/vendor/github.com/robertkrimen/otto/parser/regexp.go new file mode 100644 index 0000000..f614dae --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/parser/regexp.go @@ -0,0 +1,358 @@ +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) ", 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 ", 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 ", 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 +} diff --git a/vendor/github.com/robertkrimen/otto/parser/scope.go b/vendor/github.com/robertkrimen/otto/parser/scope.go new file mode 100644 index 0000000..e1dbdda --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/parser/scope.go @@ -0,0 +1,44 @@ +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 +} diff --git a/vendor/github.com/robertkrimen/otto/parser/statement.go b/vendor/github.com/robertkrimen/otto/parser/statement.go new file mode 100644 index 0000000..2059d38 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/parser/statement.go @@ -0,0 +1,663 @@ +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 " 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 " ;" + + 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, + File: self.file, + } +} + +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() + } +} diff --git a/vendor/github.com/robertkrimen/otto/property.go b/vendor/github.com/robertkrimen/otto/property.go new file mode 100644 index 0000000..5445ecc --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/property.go @@ -0,0 +1,220 @@ +package otto + +// property + +type _propertyMode int + +const ( + modeWriteMask _propertyMode = 0700 + modeEnumerateMask = 0070 + modeConfigureMask = 0007 + modeOnMask = 0111 + modeOffMask = 0000 + modeSetMask = 0222 // If value is 2, then mode is neither "On" nor "Off" +) + +type _propertyGetSet [2]*_object + +var _nilGetSetObject _object = _object{} + +type _property struct { + value interface{} + mode _propertyMode +} + +func (self _property) writable() bool { + return self.mode&modeWriteMask == modeWriteMask&modeOnMask +} + +func (self *_property) writeOn() { + self.mode = (self.mode & ^modeWriteMask) | (modeWriteMask & modeOnMask) +} + +func (self *_property) writeOff() { + self.mode &= ^modeWriteMask +} + +func (self *_property) writeClear() { + self.mode = (self.mode & ^modeWriteMask) | (modeWriteMask & modeSetMask) +} + +func (self _property) writeSet() bool { + return 0 == self.mode&modeWriteMask&modeSetMask +} + +func (self _property) enumerable() bool { + return self.mode&modeEnumerateMask == modeEnumerateMask&modeOnMask +} + +func (self *_property) enumerateOn() { + self.mode = (self.mode & ^modeEnumerateMask) | (modeEnumerateMask & modeOnMask) +} + +func (self *_property) enumerateOff() { + self.mode &= ^modeEnumerateMask +} + +func (self _property) enumerateSet() bool { + return 0 == self.mode&modeEnumerateMask&modeSetMask +} + +func (self _property) configurable() bool { + return self.mode&modeConfigureMask == modeConfigureMask&modeOnMask +} + +func (self *_property) configureOn() { + self.mode = (self.mode & ^modeConfigureMask) | (modeConfigureMask & modeOnMask) +} + +func (self *_property) configureOff() { + self.mode &= ^modeConfigureMask +} + +func (self _property) configureSet() bool { + return 0 == self.mode&modeConfigureMask&modeSetMask +} + +func (self _property) copy() *_property { + property := self + return &property +} + +func (self _property) get(this *_object) Value { + switch value := self.value.(type) { + case Value: + return value + case _propertyGetSet: + if value[0] != nil { + return value[0].call(toValue(this), nil, false, nativeFrame) + } + } + return Value{} +} + +func (self _property) isAccessorDescriptor() bool { + setGet, test := self.value.(_propertyGetSet) + return test && (setGet[0] != nil || setGet[1] != nil) +} + +func (self _property) isDataDescriptor() bool { + if self.writeSet() { // Either "On" or "Off" + return true + } + value, valid := self.value.(Value) + return valid && !value.isEmpty() +} + +func (self _property) isGenericDescriptor() bool { + return !(self.isDataDescriptor() || self.isAccessorDescriptor()) +} + +func (self _property) isEmpty() bool { + return self.mode == 0222 && self.isGenericDescriptor() +} + +// _enumerableValue, _enumerableTrue, _enumerableFalse? +// .enumerableValue() .enumerableExists() + +func toPropertyDescriptor(rt *_runtime, value Value) (descriptor _property) { + objectDescriptor := value._object() + if objectDescriptor == nil { + panic(rt.panicTypeError()) + } + + { + descriptor.mode = modeSetMask // Initially nothing is set + if objectDescriptor.hasProperty("enumerable") { + if objectDescriptor.get("enumerable").bool() { + descriptor.enumerateOn() + } else { + descriptor.enumerateOff() + } + } + + if objectDescriptor.hasProperty("configurable") { + if objectDescriptor.get("configurable").bool() { + descriptor.configureOn() + } else { + descriptor.configureOff() + } + } + + if objectDescriptor.hasProperty("writable") { + if objectDescriptor.get("writable").bool() { + descriptor.writeOn() + } else { + descriptor.writeOff() + } + } + } + + var getter, setter *_object + getterSetter := false + + if objectDescriptor.hasProperty("get") { + value := objectDescriptor.get("get") + if value.IsDefined() { + if !value.isCallable() { + panic(rt.panicTypeError()) + } + getter = value._object() + getterSetter = true + } else { + getter = &_nilGetSetObject + getterSetter = true + } + } + + if objectDescriptor.hasProperty("set") { + value := objectDescriptor.get("set") + if value.IsDefined() { + if !value.isCallable() { + panic(rt.panicTypeError()) + } + setter = value._object() + getterSetter = true + } else { + setter = &_nilGetSetObject + getterSetter = true + } + } + + if getterSetter { + if descriptor.writeSet() { + panic(rt.panicTypeError()) + } + descriptor.value = _propertyGetSet{getter, setter} + } + + if objectDescriptor.hasProperty("value") { + if getterSetter { + panic(rt.panicTypeError()) + } + descriptor.value = objectDescriptor.get("value") + } + + return +} + +func (self *_runtime) fromPropertyDescriptor(descriptor _property) *_object { + object := self.newObject() + if descriptor.isDataDescriptor() { + object.defineProperty("value", descriptor.value.(Value), 0111, false) + object.defineProperty("writable", toValue_bool(descriptor.writable()), 0111, false) + } else if descriptor.isAccessorDescriptor() { + getSet := descriptor.value.(_propertyGetSet) + get := Value{} + if getSet[0] != nil { + get = toValue_object(getSet[0]) + } + set := Value{} + if getSet[1] != nil { + set = toValue_object(getSet[1]) + } + object.defineProperty("get", get, 0111, false) + object.defineProperty("set", set, 0111, false) + } + object.defineProperty("enumerable", toValue_bool(descriptor.enumerable()), 0111, false) + object.defineProperty("configurable", toValue_bool(descriptor.configurable()), 0111, false) + return object +} diff --git a/vendor/github.com/robertkrimen/otto/registry/README.markdown b/vendor/github.com/robertkrimen/otto/registry/README.markdown new file mode 100644 index 0000000..ba2d389 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/registry/README.markdown @@ -0,0 +1,51 @@ +# 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 diff --git a/vendor/github.com/robertkrimen/otto/registry/registry.go b/vendor/github.com/robertkrimen/otto/registry/registry.go new file mode 100644 index 0000000..966638a --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/registry/registry.go @@ -0,0 +1,47 @@ +/* +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 +} diff --git a/vendor/github.com/robertkrimen/otto/result.go b/vendor/github.com/robertkrimen/otto/result.go new file mode 100644 index 0000000..63642e7 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/result.go @@ -0,0 +1,30 @@ +package otto + +import () + +type _resultKind int + +const ( + resultNormal _resultKind = iota + resultReturn + resultBreak + resultContinue +) + +type _result struct { + kind _resultKind + value Value + target string +} + +func newReturnResult(value Value) _result { + return _result{resultReturn, value, ""} +} + +func newContinueResult(target string) _result { + return _result{resultContinue, emptyValue, target} +} + +func newBreakResult(target string) _result { + return _result{resultBreak, emptyValue, target} +} diff --git a/vendor/github.com/robertkrimen/otto/runtime.go b/vendor/github.com/robertkrimen/otto/runtime.go new file mode 100644 index 0000000..1ac1b43 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/runtime.go @@ -0,0 +1,331 @@ +package otto + +import ( + "errors" + "reflect" + "sync" + + "github.com/robertkrimen/otto/ast" + "github.com/robertkrimen/otto/parser" +) + +type _global struct { + Object *_object // Object( ... ), new Object( ... ) - 1 (length) + Function *_object // Function( ... ), new Function( ... ) - 1 + Array *_object // Array( ... ), new Array( ... ) - 1 + String *_object // String( ... ), new String( ... ) - 1 + Boolean *_object // Boolean( ... ), new Boolean( ... ) - 1 + Number *_object // Number( ... ), new Number( ... ) - 1 + Math *_object + Date *_object // Date( ... ), new Date( ... ) - 7 + RegExp *_object // RegExp( ... ), new RegExp( ... ) - 2 + Error *_object // Error( ... ), new Error( ... ) - 1 + EvalError *_object + TypeError *_object + RangeError *_object + ReferenceError *_object + SyntaxError *_object + URIError *_object + JSON *_object + + ObjectPrototype *_object // Object.prototype + FunctionPrototype *_object // Function.prototype + ArrayPrototype *_object // Array.prototype + StringPrototype *_object // String.prototype + BooleanPrototype *_object // Boolean.prototype + NumberPrototype *_object // Number.prototype + DatePrototype *_object // Date.prototype + RegExpPrototype *_object // RegExp.prototype + ErrorPrototype *_object // Error.prototype + EvalErrorPrototype *_object + TypeErrorPrototype *_object + RangeErrorPrototype *_object + ReferenceErrorPrototype *_object + SyntaxErrorPrototype *_object + URIErrorPrototype *_object +} + +type _runtime struct { + global _global + globalObject *_object + globalStash *_objectStash + scope *_scope + otto *Otto + eval *_object // The builtin eval, for determine indirect versus direct invocation + + labels []string // FIXME + lck sync.Mutex +} + +func (self *_runtime) enterScope(scope *_scope) { + scope.outer = self.scope + self.scope = scope +} + +func (self *_runtime) leaveScope() { + self.scope = self.scope.outer +} + +// FIXME This is used in two places (cloning) +func (self *_runtime) enterGlobalScope() { + self.enterScope(newScope(self.globalStash, self.globalStash, self.globalObject)) +} + +func (self *_runtime) enterFunctionScope(outer _stash, this Value) *_fnStash { + if outer == nil { + outer = self.globalStash + } + stash := self.newFunctionStash(outer) + var thisObject *_object + switch this.kind { + case valueUndefined, valueNull: + thisObject = self.globalObject + default: + thisObject = self.toObject(this) + } + self.enterScope(newScope(stash, stash, thisObject)) + return stash +} + +func (self *_runtime) putValue(reference _reference, value Value) { + name := reference.putValue(value) + if name != "" { + // Why? -- If reference.base == nil + // strict = false + self.globalObject.defineProperty(name, value, 0111, false) + } +} + +func (self *_runtime) tryCatchEvaluate(inner func() Value) (tryValue Value, exception bool) { + // resultValue = The value of the block (e.g. the last statement) + // throw = Something was thrown + // throwValue = The value of what was thrown + // other = Something that changes flow (return, break, continue) that is not a throw + // Otherwise, some sort of unknown panic happened, we'll just propagate it + defer func() { + if caught := recover(); caught != nil { + if exception, ok := caught.(*_exception); ok { + caught = exception.eject() + } + switch caught := caught.(type) { + case _error: + exception = true + tryValue = toValue_object(self.newError(caught.name, caught.messageValue())) + case Value: + exception = true + tryValue = caught + default: + panic(caught) + } + } + }() + + tryValue = inner() + return +} + +// toObject + +func (self *_runtime) toObject(value Value) *_object { + switch value.kind { + case valueEmpty, valueUndefined, valueNull: + panic(self.panicTypeError()) + case valueBoolean: + return self.newBoolean(value) + case valueString: + return self.newString(value) + case valueNumber: + return self.newNumber(value) + case valueObject: + return value._object() + } + panic(self.panicTypeError()) +} + +func (self *_runtime) objectCoerce(value Value) (*_object, error) { + switch value.kind { + case valueUndefined: + return nil, errors.New("undefined") + case valueNull: + return nil, errors.New("null") + case valueBoolean: + return self.newBoolean(value), nil + case valueString: + return self.newString(value), nil + case valueNumber: + return self.newNumber(value), nil + case valueObject: + return value._object(), nil + } + panic(self.panicTypeError()) +} + +func checkObjectCoercible(rt *_runtime, value Value) { + isObject, mustCoerce := testObjectCoercible(value) + if !isObject && !mustCoerce { + panic(rt.panicTypeError()) + } +} + +// testObjectCoercible + +func testObjectCoercible(value Value) (isObject bool, mustCoerce bool) { + switch value.kind { + case valueReference, valueEmpty, valueNull, valueUndefined: + return false, false + case valueNumber, valueString, valueBoolean: + isObject = false + mustCoerce = true + case valueObject: + isObject = true + mustCoerce = false + } + return +} + +func (self *_runtime) safeToValue(value interface{}) (Value, error) { + result := Value{} + err := catchPanic(func() { + result = self.toValue(value) + }) + return result, err +} + +func (self *_runtime) toValue(value interface{}) Value { + switch value := value.(type) { + case Value: + return value + case func(FunctionCall) Value: + return toValue_object(self.newNativeFunction("", value)) + case _nativeFunction: + return toValue_object(self.newNativeFunction("", value)) + case Object, *Object, _object, *_object: + // Nothing happens. + // FIXME We should really figure out what can come here. + // This catch-all is ugly. + default: + { + value := reflect.ValueOf(value) + switch value.Kind() { + case reflect.Ptr: + switch reflect.Indirect(value).Kind() { + case reflect.Struct: + return toValue_object(self.newGoStructObject(value)) + case reflect.Array: + return toValue_object(self.newGoArray(value)) + } + case reflect.Func: + // TODO Maybe cache this? + return toValue_object(self.newNativeFunction("", func(call FunctionCall) Value { + in := make([]reflect.Value, len(call.ArgumentList)) + for i, value := range call.ArgumentList { + in[i] = reflect.ValueOf(value.export()) + } + + out := value.Call(in) + if len(out) == 1 { + return self.toValue(out[0].Interface()) + } else if len(out) == 0 { + return Value{} + } + + panic(call.runtime.panicTypeError()) + })) + case reflect.Struct: + return toValue_object(self.newGoStructObject(value)) + case reflect.Map: + return toValue_object(self.newGoMapObject(value)) + case reflect.Slice: + return toValue_object(self.newGoSlice(value)) + case reflect.Array: + return toValue_object(self.newGoArray(value)) + } + } + } + return toValue(value) +} + +func (runtime *_runtime) newGoSlice(value reflect.Value) *_object { + self := runtime.newGoSliceObject(value) + self.prototype = runtime.global.ArrayPrototype + return self +} + +func (runtime *_runtime) newGoArray(value reflect.Value) *_object { + self := runtime.newGoArrayObject(value) + self.prototype = runtime.global.ArrayPrototype + return self +} + +func (runtime *_runtime) parse(filename string, src interface{}) (*ast.Program, error) { + return parser.ParseFile(nil, filename, src, 0) +} + +func (runtime *_runtime) cmpl_parse(filename string, src interface{}) (*_nodeProgram, error) { + program, err := parser.ParseFile(nil, filename, src, 0) + if err != nil { + return nil, err + } + return cmpl_parse(program), nil +} + +func (self *_runtime) parseSource(src interface{}) (*_nodeProgram, *ast.Program, error) { + switch src := src.(type) { + case *ast.Program: + return nil, src, nil + case *Script: + return src.program, nil, nil + } + program, err := self.parse("", src) + return nil, program, err +} + +func (self *_runtime) cmpl_run(src interface{}) (Value, error) { + result := Value{} + cmpl_program, program, err := self.parseSource(src) + if err != nil { + return result, err + } + if cmpl_program == nil { + cmpl_program = cmpl_parse(program) + } + err = catchPanic(func() { + result = self.cmpl_evaluate_nodeProgram(cmpl_program, false) + }) + switch result.kind { + case valueEmpty: + result = Value{} + case valueReference: + result = result.resolve() + } + return result, err +} + +func (self *_runtime) parseThrow(err error) { + if err == nil { + return + } + switch err := err.(type) { + case parser.ErrorList: + { + err := err[0] + if err.Message == "Invalid left-hand side in assignment" { + panic(self.panicReferenceError(err.Message)) + } + panic(self.panicSyntaxError(err.Message)) + } + } + panic(self.panicSyntaxError(err.Error())) +} + +func (self *_runtime) parseOrThrow(source string) *ast.Program { + program, err := self.parse("", source) + self.parseThrow(err) // Will panic/throw appropriately + return program +} + +func (self *_runtime) cmpl_parseOrThrow(source string) *_nodeProgram { + program, err := self.cmpl_parse("", source) + self.parseThrow(err) // Will panic/throw appropriately + return program +} diff --git a/vendor/github.com/robertkrimen/otto/scope.go b/vendor/github.com/robertkrimen/otto/scope.go new file mode 100644 index 0000000..b808084 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/scope.go @@ -0,0 +1,34 @@ +package otto + +// _scope: +// entryFile +// entryIdx +// top? +// outer => nil + +// _stash: +// lexical +// variable +// +// _thisStash (ObjectEnvironment) +// _fnStash +// _dclStash + +// An ECMA-262 ExecutionContext +type _scope struct { + lexical _stash + variable _stash + this *_object + eval bool // Replace this with kind? + outer *_scope + + frame _frame +} + +func newScope(lexical _stash, variable _stash, this *_object) *_scope { + return &_scope{ + lexical: lexical, + variable: variable, + this: this, + } +} diff --git a/vendor/github.com/robertkrimen/otto/script.go b/vendor/github.com/robertkrimen/otto/script.go new file mode 100644 index 0000000..ed8aebb --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/script.go @@ -0,0 +1,122 @@ +package otto + +import ( + "bytes" + "encoding/gob" + "errors" + + "github.com/robertkrimen/otto/parser" +) + +var ErrVersion = errors.New("version mismatch") + +var scriptVersion = "2014-04-13/1" + +// Script is a handle for some (reusable) JavaScript. +// Passing a Script value to a run method will evaluate the JavaScript. +// +type Script struct { + version string + program *_nodeProgram + filename string + src string +} + +// Compile will parse the given source and return a Script value or nil and +// an error if there was a problem during compilation. +// +// script, err := vm.Compile("", `var abc; if (!abc) abc = 0; abc += 2; abc;`) +// vm.Run(script) +// +func (self *Otto) Compile(filename string, src interface{}) (*Script, error) { + { + src, err := parser.ReadSource(filename, src) + if err != nil { + return nil, err + } + + program, err := self.runtime.parse(filename, src) + if err != nil { + return nil, err + } + + cmpl_program := cmpl_parse(program) + + script := &Script{ + version: scriptVersion, + program: cmpl_program, + filename: filename, + src: string(src), + } + + return script, nil + } +} + +func (self *Script) String() string { + return "// " + self.filename + "\n" + self.src +} + +// MarshalBinary will marshal a script into a binary form. A marshalled script +// that is later unmarshalled can be executed on the same version of the otto runtime. +// +// The binary format can change at any time and should be considered unspecified and opaque. +// +func (self *Script) marshalBinary() ([]byte, error) { + var bfr bytes.Buffer + encoder := gob.NewEncoder(&bfr) + err := encoder.Encode(self.version) + if err != nil { + return nil, err + } + err = encoder.Encode(self.program) + if err != nil { + return nil, err + } + err = encoder.Encode(self.filename) + if err != nil { + return nil, err + } + err = encoder.Encode(self.src) + if err != nil { + return nil, err + } + return bfr.Bytes(), nil +} + +// UnmarshalBinary will vivify a marshalled script into something usable. If the script was +// originally marshalled on a different version of the otto runtime, then this method +// will return an error. +// +// The binary format can change at any time and should be considered unspecified and opaque. +// +func (self *Script) unmarshalBinary(data []byte) error { + decoder := gob.NewDecoder(bytes.NewReader(data)) + err := decoder.Decode(&self.version) + if err != nil { + goto error + } + if self.version != scriptVersion { + err = ErrVersion + goto error + } + err = decoder.Decode(&self.program) + if err != nil { + goto error + } + err = decoder.Decode(&self.filename) + if err != nil { + goto error + } + err = decoder.Decode(&self.src) + if err != nil { + goto error + } + return nil +error: + self.version = "" + self.program = nil + self.filename = "" + self.src = "" + return err +} diff --git a/vendor/github.com/robertkrimen/otto/stash.go b/vendor/github.com/robertkrimen/otto/stash.go new file mode 100644 index 0000000..578708d --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/stash.go @@ -0,0 +1,275 @@ +package otto + +import ( + "fmt" +) + +// ====== +// _stash +// ====== + +type _stash interface { + hasBinding(string) bool // + createBinding(string, bool, Value) // CreateMutableBinding + setBinding(string, Value, bool) // SetMutableBinding + getBinding(string, bool) Value // GetBindingValue + deleteBinding(string) bool // + setValue(string, Value, bool) // createBinding + setBinding + + outer() _stash + runtime() *_runtime + + newReference(string, bool, _at) _reference + + clone(clone *_clone) _stash +} + +// ========== +// _objectStash +// ========== + +type _objectStash struct { + _runtime *_runtime + _outer _stash + object *_object +} + +func (self *_objectStash) runtime() *_runtime { + return self._runtime +} + +func (runtime *_runtime) newObjectStash(object *_object, outer _stash) *_objectStash { + if object == nil { + object = runtime.newBaseObject() + object.class = "environment" + } + return &_objectStash{ + _runtime: runtime, + _outer: outer, + object: object, + } +} + +func (in *_objectStash) clone(clone *_clone) _stash { + out, exists := clone.objectStash(in) + if exists { + return out + } + *out = _objectStash{ + clone.runtime, + clone.stash(in._outer), + clone.object(in.object), + } + return out +} + +func (self *_objectStash) hasBinding(name string) bool { + return self.object.hasProperty(name) +} + +func (self *_objectStash) createBinding(name string, deletable bool, value Value) { + if self.object.hasProperty(name) { + panic(hereBeDragons()) + } + mode := _propertyMode(0111) + if !deletable { + mode = _propertyMode(0110) + } + // TODO False? + self.object.defineProperty(name, value, mode, false) +} + +func (self *_objectStash) setBinding(name string, value Value, strict bool) { + self.object.put(name, value, strict) +} + +func (self *_objectStash) setValue(name string, value Value, throw bool) { + if !self.hasBinding(name) { + self.createBinding(name, true, value) // Configurable by default + } else { + self.setBinding(name, value, throw) + } +} + +func (self *_objectStash) getBinding(name string, throw bool) Value { + if self.object.hasProperty(name) { + return self.object.get(name) + } + if throw { // strict? + panic(self._runtime.panicReferenceError("Not Defined", name)) + } + return Value{} +} + +func (self *_objectStash) deleteBinding(name string) bool { + return self.object.delete(name, false) +} + +func (self *_objectStash) outer() _stash { + return self._outer +} + +func (self *_objectStash) newReference(name string, strict bool, at _at) _reference { + return newPropertyReference(self._runtime, self.object, name, strict, at) +} + +// ========= +// _dclStash +// ========= + +type _dclStash struct { + _runtime *_runtime + _outer _stash + property map[string]_dclProperty +} + +type _dclProperty struct { + value Value + mutable bool + deletable bool + readable bool +} + +func (runtime *_runtime) newDeclarationStash(outer _stash) *_dclStash { + return &_dclStash{ + _runtime: runtime, + _outer: outer, + property: map[string]_dclProperty{}, + } +} + +func (in *_dclStash) clone(clone *_clone) _stash { + out, exists := clone.dclStash(in) + if exists { + return out + } + property := make(map[string]_dclProperty, len(in.property)) + for index, value := range in.property { + property[index] = clone.dclProperty(value) + } + *out = _dclStash{ + clone.runtime, + clone.stash(in._outer), + property, + } + return out +} + +func (self *_dclStash) hasBinding(name string) bool { + _, exists := self.property[name] + return exists +} + +func (self *_dclStash) runtime() *_runtime { + return self._runtime +} + +func (self *_dclStash) createBinding(name string, deletable bool, value Value) { + _, exists := self.property[name] + if exists { + panic(fmt.Errorf("createBinding: %s: already exists", name)) + } + self.property[name] = _dclProperty{ + value: value, + mutable: true, + deletable: deletable, + readable: false, + } +} + +func (self *_dclStash) setBinding(name string, value Value, strict bool) { + property, exists := self.property[name] + if !exists { + panic(fmt.Errorf("setBinding: %s: missing", name)) + } + if property.mutable { + property.value = value + self.property[name] = property + } else { + self._runtime.typeErrorResult(strict) + } +} + +func (self *_dclStash) setValue(name string, value Value, throw bool) { + if !self.hasBinding(name) { + self.createBinding(name, false, value) // NOT deletable by default + } else { + self.setBinding(name, value, throw) + } +} + +// FIXME This is called a __lot__ +func (self *_dclStash) getBinding(name string, throw bool) Value { + property, exists := self.property[name] + if !exists { + panic(fmt.Errorf("getBinding: %s: missing", name)) + } + if !property.mutable && !property.readable { + if throw { // strict? + panic(self._runtime.panicTypeError()) + } + return Value{} + } + return property.value +} + +func (self *_dclStash) 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 *_dclStash) outer() _stash { + return self._outer +} + +func (self *_dclStash) newReference(name string, strict bool, _ _at) _reference { + return &_stashReference{ + name: name, + base: self, + } +} + +// ======== +// _fnStash +// ======== + +type _fnStash struct { + _dclStash + arguments *_object + indexOfArgumentName map[string]string +} + +func (runtime *_runtime) newFunctionStash(outer _stash) *_fnStash { + return &_fnStash{ + _dclStash: _dclStash{ + _runtime: runtime, + _outer: outer, + property: map[string]_dclProperty{}, + }, + } +} + +func (in *_fnStash) clone(clone *_clone) _stash { + out, exists := clone.fnStash(in) + if exists { + return out + } + dclStash := in._dclStash.clone(clone).(*_dclStash) + index := make(map[string]string, len(in.indexOfArgumentName)) + for name, value := range in.indexOfArgumentName { + index[name] = value + } + *out = _fnStash{ + _dclStash: *dclStash, + arguments: clone.object(in.arguments), + indexOfArgumentName: index, + } + return out +} diff --git a/vendor/github.com/robertkrimen/otto/token/Makefile b/vendor/github.com/robertkrimen/otto/token/Makefile new file mode 100644 index 0000000..1e85c73 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/token/Makefile @@ -0,0 +1,2 @@ +token_const.go: tokenfmt + ./$^ | gofmt > $@ diff --git a/vendor/github.com/robertkrimen/otto/token/README.markdown b/vendor/github.com/robertkrimen/otto/token/README.markdown new file mode 100644 index 0000000..ff3b161 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/token/README.markdown @@ -0,0 +1,171 @@ +# 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 diff --git a/vendor/github.com/robertkrimen/otto/token/token.go b/vendor/github.com/robertkrimen/otto/token/token.go new file mode 100644 index 0000000..0e941ac --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/token/token.go @@ -0,0 +1,116 @@ +// 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 +} diff --git a/vendor/github.com/robertkrimen/otto/token/token_const.go b/vendor/github.com/robertkrimen/otto/token/token_const.go new file mode 100644 index 0000000..b1d83c6 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/token/token_const.go @@ -0,0 +1,349 @@ +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, + }, +} diff --git a/vendor/github.com/robertkrimen/otto/token/tokenfmt b/vendor/github.com/robertkrimen/otto/token/tokenfmt new file mode 100755 index 0000000..63dd5d9 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/token/tokenfmt @@ -0,0 +1,222 @@ +#!/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_ +} diff --git a/vendor/github.com/robertkrimen/otto/type_arguments.go b/vendor/github.com/robertkrimen/otto/type_arguments.go new file mode 100644 index 0000000..841d758 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_arguments.go @@ -0,0 +1,106 @@ +package otto + +import ( + "strconv" +) + +func (runtime *_runtime) newArgumentsObject(indexOfParameterName []string, stash _stash, length int) *_object { + self := runtime.newClassObject("Arguments") + + for index, _ := range indexOfParameterName { + name := strconv.FormatInt(int64(index), 10) + objectDefineOwnProperty(self, name, _property{Value{}, 0111}, false) + } + + self.objectClass = _classArguments + self.value = _argumentsObject{ + indexOfParameterName: indexOfParameterName, + stash: stash, + } + + self.prototype = runtime.global.ObjectPrototype + + self.defineProperty("length", toValue_int(length), 0101, false) + + return self +} + +type _argumentsObject struct { + indexOfParameterName []string + // function(abc, def, ghi) + // indexOfParameterName[0] = "abc" + // indexOfParameterName[1] = "def" + // indexOfParameterName[2] = "ghi" + // ... + stash _stash +} + +func (in _argumentsObject) clone(clone *_clone) _argumentsObject { + indexOfParameterName := make([]string, len(in.indexOfParameterName)) + copy(indexOfParameterName, in.indexOfParameterName) + return _argumentsObject{ + indexOfParameterName, + clone.stash(in.stash), + } +} + +func (self _argumentsObject) get(name string) (Value, bool) { + index := stringToArrayIndex(name) + if index >= 0 && index < int64(len(self.indexOfParameterName)) { + name := self.indexOfParameterName[index] + if name == "" { + return Value{}, false + } + return self.stash.getBinding(name, false), true + } + return Value{}, false +} + +func (self _argumentsObject) put(name string, value Value) { + index := stringToArrayIndex(name) + name = self.indexOfParameterName[index] + self.stash.setBinding(name, value, false) +} + +func (self _argumentsObject) delete(name string) { + index := stringToArrayIndex(name) + self.indexOfParameterName[index] = "" +} + +func argumentsGet(self *_object, name string) Value { + if value, exists := self.value.(_argumentsObject).get(name); exists { + return value + } + return objectGet(self, name) +} + +func argumentsGetOwnProperty(self *_object, name string) *_property { + property := objectGetOwnProperty(self, name) + if value, exists := self.value.(_argumentsObject).get(name); exists { + property.value = value + } + return property +} + +func argumentsDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { + if _, exists := self.value.(_argumentsObject).get(name); exists { + if !objectDefineOwnProperty(self, name, descriptor, false) { + return self.runtime.typeErrorResult(throw) + } + if value, valid := descriptor.value.(Value); valid { + self.value.(_argumentsObject).put(name, value) + } + return true + } + return objectDefineOwnProperty(self, name, descriptor, throw) +} + +func argumentsDelete(self *_object, name string, throw bool) bool { + if !objectDelete(self, name, throw) { + return false + } + if _, exists := self.value.(_argumentsObject).get(name); exists { + self.value.(_argumentsObject).delete(name) + } + return true +} diff --git a/vendor/github.com/robertkrimen/otto/type_array.go b/vendor/github.com/robertkrimen/otto/type_array.go new file mode 100644 index 0000000..236376a --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_array.go @@ -0,0 +1,109 @@ +package otto + +import ( + "strconv" +) + +func (runtime *_runtime) newArrayObject(length uint32) *_object { + self := runtime.newObject() + self.class = "Array" + self.defineProperty("length", toValue_uint32(length), 0100, false) + self.objectClass = _classArray + return self +} + +func isArray(object *_object) bool { + return object != nil && (object.class == "Array" || object.class == "GoArray") +} + +func objectLength(object *_object) uint32 { + if object == nil { + return 0 + } + switch object.class { + case "Array": + return object.get("length").value.(uint32) + case "String": + return uint32(object.get("length").value.(int)) + case "GoArray": + return uint32(object.get("length").value.(int)) + } + return 0 +} + +func arrayUint32(rt *_runtime, value Value) uint32 { + nm := value.number() + if nm.kind != numberInteger || !isUint32(nm.int64) { + // FIXME + panic(rt.panicRangeError()) + } + return uint32(nm.int64) +} + +func arrayDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { + lengthProperty := self.getOwnProperty("length") + lengthValue, valid := lengthProperty.value.(Value) + if !valid { + panic("Array.length != Value{}") + } + length := lengthValue.value.(uint32) + if name == "length" { + if descriptor.value == nil { + return objectDefineOwnProperty(self, name, descriptor, throw) + } + newLengthValue, isValue := descriptor.value.(Value) + if !isValue { + panic(self.runtime.panicTypeError()) + } + newLength := arrayUint32(self.runtime, newLengthValue) + descriptor.value = toValue_uint32(newLength) + if newLength > length { + return objectDefineOwnProperty(self, name, descriptor, throw) + } + if !lengthProperty.writable() { + goto Reject + } + newWritable := true + if descriptor.mode&0700 == 0 { + // If writable is off + newWritable = false + descriptor.mode |= 0100 + } + if !objectDefineOwnProperty(self, name, descriptor, throw) { + return false + } + for newLength < length { + length -= 1 + if !self.delete(strconv.FormatInt(int64(length), 10), false) { + descriptor.value = toValue_uint32(length + 1) + if !newWritable { + descriptor.mode &= 0077 + } + objectDefineOwnProperty(self, name, descriptor, false) + goto Reject + } + } + if !newWritable { + descriptor.mode &= 0077 + objectDefineOwnProperty(self, name, descriptor, false) + } + } else if index := stringToArrayIndex(name); index >= 0 { + if index >= int64(length) && !lengthProperty.writable() { + goto Reject + } + if !objectDefineOwnProperty(self, strconv.FormatInt(index, 10), descriptor, false) { + goto Reject + } + if index >= int64(length) { + lengthProperty.value = toValue_uint32(uint32(index + 1)) + objectDefineOwnProperty(self, "length", *lengthProperty, false) + return true + } + } + return objectDefineOwnProperty(self, name, descriptor, throw) +Reject: + if throw { + panic(self.runtime.panicTypeError()) + } + return false +} diff --git a/vendor/github.com/robertkrimen/otto/type_boolean.go b/vendor/github.com/robertkrimen/otto/type_boolean.go new file mode 100644 index 0000000..afc45c6 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_boolean.go @@ -0,0 +1,13 @@ +package otto + +import ( + "strconv" +) + +func (runtime *_runtime) newBooleanObject(value Value) *_object { + return runtime.newPrimitiveObject("Boolean", toValue_bool(value.bool())) +} + +func booleanToString(value bool) string { + return strconv.FormatBool(value) +} diff --git a/vendor/github.com/robertkrimen/otto/type_date.go b/vendor/github.com/robertkrimen/otto/type_date.go new file mode 100644 index 0000000..7079e64 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_date.go @@ -0,0 +1,299 @@ +package otto + +import ( + "fmt" + "math" + "regexp" + Time "time" +) + +type _dateObject struct { + time Time.Time // Time from the "time" package, a cached version of time + epoch int64 + value Value + isNaN bool +} + +var ( + invalidDateObject = _dateObject{ + time: Time.Time{}, + epoch: -1, + value: NaNValue(), + isNaN: true, + } +) + +type _ecmaTime struct { + year int + month int + day int + hour int + minute int + second int + millisecond int + location *Time.Location // Basically, either local or UTC +} + +func ecmaTime(goTime Time.Time) _ecmaTime { + return _ecmaTime{ + goTime.Year(), + dateFromGoMonth(goTime.Month()), + goTime.Day(), + goTime.Hour(), + goTime.Minute(), + goTime.Second(), + goTime.Nanosecond() / (100 * 100 * 100), + goTime.Location(), + } +} + +func (self *_ecmaTime) goTime() Time.Time { + return Time.Date( + self.year, + dateToGoMonth(self.month), + self.day, + self.hour, + self.minute, + self.second, + self.millisecond*(100*100*100), + self.location, + ) +} + +func (self *_dateObject) Time() Time.Time { + return self.time +} + +func (self *_dateObject) Epoch() int64 { + return self.epoch +} + +func (self *_dateObject) Value() Value { + return self.value +} + +// FIXME A date should only be in the range of -100,000,000 to +100,000,000 (1970): 15.9.1.1 +func (self *_dateObject) SetNaN() { + self.time = Time.Time{} + self.epoch = -1 + self.value = NaNValue() + self.isNaN = true +} + +func (self *_dateObject) SetTime(time Time.Time) { + self.Set(timeToEpoch(time)) +} + +func epoch2dateObject(epoch float64) _dateObject { + date := _dateObject{} + date.Set(epoch) + return date +} + +func (self *_dateObject) Set(epoch float64) { + // epoch + self.epoch = epochToInteger(epoch) + + // time + time, err := epochToTime(epoch) + self.time = time // Is either a valid time, or the zero-value for time.Time + + // value & isNaN + if err != nil { + self.isNaN = true + self.epoch = -1 + self.value = NaNValue() + } else { + self.value = toValue_int64(self.epoch) + } +} + +func epochToInteger(value float64) int64 { + if value > 0 { + return int64(math.Floor(value)) + } + return int64(math.Ceil(value)) +} + +func epochToTime(value float64) (time Time.Time, err error) { + epochWithMilli := value + if math.IsNaN(epochWithMilli) || math.IsInf(epochWithMilli, 0) { + err = fmt.Errorf("Invalid time %v", value) + return + } + + epoch := int64(epochWithMilli / 1000) + milli := int64(epochWithMilli) % 1000 + + time = Time.Unix(int64(epoch), milli*1000000).UTC() + return +} + +func timeToEpoch(time Time.Time) float64 { + return float64(time.UnixNano() / (1000 * 1000)) +} + +func (runtime *_runtime) newDateObject(epoch float64) *_object { + self := runtime.newObject() + self.class = "Date" + + // FIXME This is ugly... + date := _dateObject{} + date.Set(epoch) + self.value = date + return self +} + +func (self *_object) dateValue() _dateObject { + value, _ := self.value.(_dateObject) + return value +} + +func dateObjectOf(rt *_runtime, _dateObject *_object) _dateObject { + if _dateObject == nil || _dateObject.class != "Date" { + panic(rt.panicTypeError()) + } + return _dateObject.dateValue() +} + +// JavaScript is 0-based, Go is 1-based (15.9.1.4) +func dateToGoMonth(month int) Time.Month { + return Time.Month(month + 1) +} + +func dateFromGoMonth(month Time.Month) int { + return int(month) - 1 +} + +// Both JavaScript & Go are 0-based (Sunday == 0) +func dateToGoDay(day int) Time.Weekday { + return Time.Weekday(day) +} + +func dateFromGoDay(day Time.Weekday) int { + return int(day) +} + +func newDateTime(argumentList []Value, location *Time.Location) (epoch float64) { + + pick := func(index int, default_ float64) (float64, bool) { + if index >= len(argumentList) { + return default_, false + } + value := argumentList[index].float64() + if math.IsNaN(value) || math.IsInf(value, 0) { + return 0, true + } + return value, false + } + + if len(argumentList) >= 2 { // 2-argument, 3-argument, ... + var year, month, day, hour, minute, second, millisecond float64 + var invalid bool + if year, invalid = pick(0, 1900.0); invalid { + goto INVALID + } + if month, invalid = pick(1, 0.0); invalid { + goto INVALID + } + if day, invalid = pick(2, 1.0); invalid { + goto INVALID + } + if hour, invalid = pick(3, 0.0); invalid { + goto INVALID + } + if minute, invalid = pick(4, 0.0); invalid { + goto INVALID + } + if second, invalid = pick(5, 0.0); invalid { + goto INVALID + } + if millisecond, invalid = pick(6, 0.0); invalid { + goto INVALID + } + + if year >= 0 && year <= 99 { + year += 1900 + } + + time := Time.Date(int(year), dateToGoMonth(int(month)), int(day), int(hour), int(minute), int(second), int(millisecond)*1000*1000, location) + return timeToEpoch(time) + + } else if len(argumentList) == 0 { // 0-argument + time := Time.Now().UTC() + return timeToEpoch(time) + } else { // 1-argument + value := valueOfArrayIndex(argumentList, 0) + value = toPrimitive(value) + if value.IsString() { + return dateParse(value.string()) + } + + return value.float64() + } + +INVALID: + epoch = math.NaN() + return +} + +var ( + dateLayoutList = []string{ + "2006", + "2006-01", + "2006-01-02", + + "2006T15:04", + "2006-01T15:04", + "2006-01-02T15:04", + + "2006T15:04:05", + "2006-01T15:04:05", + "2006-01-02T15:04:05", + + "2006T15:04:05.000", + "2006-01T15:04:05.000", + "2006-01-02T15:04:05.000", + + "2006T15:04-0700", + "2006-01T15:04-0700", + "2006-01-02T15:04-0700", + + "2006T15:04:05-0700", + "2006-01T15:04:05-0700", + "2006-01-02T15:04:05-0700", + + "2006T15:04:05.000-0700", + "2006-01T15:04:05.000-0700", + "2006-01-02T15:04:05.000-0700", + + Time.RFC1123, + } + matchDateTimeZone = regexp.MustCompile(`^(.*)(?:(Z)|([\+\-]\d{2}):(\d{2}))$`) +) + +func dateParse(date string) (epoch float64) { + // YYYY-MM-DDTHH:mm:ss.sssZ + var time Time.Time + var err error + { + date := date + if match := matchDateTimeZone.FindStringSubmatch(date); match != nil { + if match[2] == "Z" { + date = match[1] + "+0000" + } else { + date = match[1] + match[3] + match[4] + } + } + for _, layout := range dateLayoutList { + time, err = Time.Parse(layout, date) + if err == nil { + break + } + } + } + if err != nil { + return math.NaN() + } + return float64(time.UnixNano()) / (1000 * 1000) // UnixMilli() +} diff --git a/vendor/github.com/robertkrimen/otto/type_error.go b/vendor/github.com/robertkrimen/otto/type_error.go new file mode 100644 index 0000000..c469f5f --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_error.go @@ -0,0 +1,13 @@ +package otto + +func (rt *_runtime) newErrorObject(name string, message Value) *_object { + self := rt.newClassObject("Error") + if message.IsDefined() { + msg := message.string() + self.defineProperty("message", toValue_string(msg), 0111, false) + self.value = newError(rt, name, msg) + } else { + self.value = newError(rt, name) + } + return self +} diff --git a/vendor/github.com/robertkrimen/otto/type_function.go b/vendor/github.com/robertkrimen/otto/type_function.go new file mode 100644 index 0000000..a5eb755 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_function.go @@ -0,0 +1,262 @@ +package otto + +// _constructFunction +type _constructFunction func(*_object, []Value) Value + +// 13.2.2 [[Construct]] +func defaultConstruct(fn *_object, argumentList []Value) Value { + object := fn.runtime.newObject() + object.class = "Object" + + prototype := fn.get("prototype") + if prototype.kind != valueObject { + prototype = toValue_object(fn.runtime.global.ObjectPrototype) + } + object.prototype = prototype._object() + + this := toValue_object(object) + value := fn.call(this, argumentList, false, nativeFrame) + if value.kind == valueObject { + return value + } + return this +} + +// _nativeFunction +type _nativeFunction func(FunctionCall) Value + +// ===================== // +// _nativeFunctionObject // +// ===================== // + +type _nativeFunctionObject struct { + name string + call _nativeFunction // [[Call]] + construct _constructFunction // [[Construct]] +} + +func (runtime *_runtime) newNativeFunctionObject(name string, native _nativeFunction, length int) *_object { + self := runtime.newClassObject("Function") + self.value = _nativeFunctionObject{ + call: native, + construct: defaultConstruct, + } + self.defineProperty("length", toValue_int(length), 0000, false) + return self +} + +// =================== // +// _bindFunctionObject // +// =================== // + +type _bindFunctionObject struct { + target *_object + this Value + argumentList []Value +} + +func (runtime *_runtime) newBoundFunctionObject(target *_object, this Value, argumentList []Value) *_object { + self := runtime.newClassObject("Function") + self.value = _bindFunctionObject{ + target: target, + this: this, + argumentList: argumentList, + } + 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", Value{}, 0000, false) // TODO Should throw a TypeError + self.defineProperty("arguments", Value{}, 0000, false) // TODO Should throw a TypeError + return self +} + +// [[Construct]] +func (fn _bindFunctionObject) construct(argumentList []Value) Value { + object := fn.target + switch value := object.value.(type) { + case _nativeFunctionObject: + return value.construct(object, fn.argumentList) + case _nodeFunctionObject: + argumentList = append(fn.argumentList, argumentList...) + return object.construct(argumentList) + } + panic(fn.target.runtime.panicTypeError()) +} + +// =================== // +// _nodeFunctionObject // +// =================== // + +type _nodeFunctionObject struct { + node *_nodeFunctionLiteral + stash _stash +} + +func (runtime *_runtime) newNodeFunctionObject(node *_nodeFunctionLiteral, stash _stash) *_object { + self := runtime.newClassObject("Function") + self.value = _nodeFunctionObject{ + node: node, + stash: stash, + } + self.defineProperty("length", toValue_int(len(node.parameterList)), 0000, false) + return self +} + +// ======= // +// _object // +// ======= // + +func (self *_object) isCall() bool { + switch fn := self.value.(type) { + case _nativeFunctionObject: + return fn.call != nil + case _bindFunctionObject: + return true + case _nodeFunctionObject: + return true + } + return false +} + +func (self *_object) call(this Value, argumentList []Value, eval bool, frame _frame) Value { + switch fn := self.value.(type) { + + case _nativeFunctionObject: + // TODO Enter a scope, name from the native object... + // Since eval is a native function, we only have to check for it here + if eval { + eval = self == self.runtime.eval // If eval is true, then it IS a direct eval + } + return fn.call(FunctionCall{ + runtime: self.runtime, + eval: eval, + + This: this, + ArgumentList: argumentList, + Otto: self.runtime.otto, + }) + + case _bindFunctionObject: + // TODO Passthrough site, do not enter a scope + argumentList = append(fn.argumentList, argumentList...) + return fn.target.call(fn.this, argumentList, false, frame) + + case _nodeFunctionObject: + rt := self.runtime + stash := rt.enterFunctionScope(fn.stash, this) + defer func() { + rt.leaveScope() + }() + rt.scope.frame = frame + callValue := rt.cmpl_call_nodeFunction(self, stash, fn.node, this, argumentList) + if value, valid := callValue.value.(_result); valid { + return value.value + } + return callValue + } + + panic(self.runtime.panicTypeError("%v is not a function", toValue_object(self))) +} + +func (self *_object) construct(argumentList []Value) Value { + switch fn := self.value.(type) { + + case _nativeFunctionObject: + if fn.call == nil { + panic(self.runtime.panicTypeError("%v is not a function", toValue_object(self))) + } + if fn.construct == nil { + panic(self.runtime.panicTypeError("%v is not a constructor", toValue_object(self))) + } + return fn.construct(self, argumentList) + + case _bindFunctionObject: + return fn.construct(argumentList) + + case _nodeFunctionObject: + return defaultConstruct(self, argumentList) + } + + panic(self.runtime.panicTypeError("%v is not a function", toValue_object(self))) +} + +// 15.3.5.3 +func (self *_object) hasInstance(of Value) bool { + if !self.isCall() { + // We should not have a hasInstance method + panic(self.runtime.panicTypeError()) + } + if !of.IsObject() { + return false + } + prototype := self.get("prototype") + if !prototype.IsObject() { + panic(self.runtime.panicTypeError()) + } + prototypeObject := prototype._object() + + value := of._object().prototype + for value != nil { + if value == prototypeObject { + return true + } + value = value.prototype + } + return false +} + +// ============ // +// FunctionCall // +// ============ // + +// FunctionCall is an encapsulation of a JavaScript function call. +type FunctionCall struct { + runtime *_runtime + _thisObject *_object + eval bool // This call is a direct call to eval + + 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.This.resolve() // 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(self.runtime.panicTypeError()) + } + return self._thisObject +} + +func (self FunctionCall) toObject(value Value) *_object { + return self.runtime.toObject(value) +} diff --git a/vendor/github.com/robertkrimen/otto/type_go_array.go b/vendor/github.com/robertkrimen/otto/type_go_array.go new file mode 100644 index 0000000..13a0b10 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_go_array.go @@ -0,0 +1,134 @@ +package otto + +import ( + "reflect" + "strconv" +) + +func (runtime *_runtime) newGoArrayObject(value reflect.Value) *_object { + self := runtime.newObject() + self.class = "GoArray" + self.objectClass = _classGoArray + self.value = _newGoArrayObject(value) + return self +} + +type _goArrayObject struct { + value reflect.Value + writable bool + propertyMode _propertyMode +} + +func _newGoArrayObject(value reflect.Value) *_goArrayObject { + writable := value.Kind() == reflect.Ptr // The Array is addressable (like a Slice) + mode := _propertyMode(0010) + if writable { + mode = 0110 + } + self := &_goArrayObject{ + value: value, + writable: writable, + propertyMode: mode, + } + return self +} + +func (self _goArrayObject) getValue(index int64) (reflect.Value, bool) { + value := reflect.Indirect(self.value) + if index < int64(value.Len()) { + return value.Index(int(index)), true + } + return reflect.Value{}, false +} + +func (self _goArrayObject) setValue(index int64, value Value) bool { + indexValue, exists := self.getValue(index) + if !exists { + return false + } + reflectValue, err := value.toReflectValue(reflect.Indirect(self.value).Type().Elem().Kind()) + if err != nil { + panic(err) + } + indexValue.Set(reflectValue) + return true +} + +func goArrayGetOwnProperty(self *_object, name string) *_property { + // length + if name == "length" { + return &_property{ + value: toValue(reflect.Indirect(self.value.(*_goArrayObject).value).Len()), + mode: 0, + } + } + + // .0, .1, .2, ... + index := stringToArrayIndex(name) + if index >= 0 { + object := self.value.(*_goArrayObject) + value := Value{} + reflectValue, exists := object.getValue(index) + if exists { + value = self.runtime.toValue(reflectValue.Interface()) + } + return &_property{ + value: value, + mode: object.propertyMode, + } + } + + return objectGetOwnProperty(self, name) +} + +func goArrayEnumerate(self *_object, all bool, each func(string) bool) { + object := self.value.(*_goArrayObject) + // .0, .1, .2, ... + + for index, length := 0, object.value.Len(); index < length; index++ { + name := strconv.FormatInt(int64(index), 10) + if !each(name) { + return + } + } + + objectEnumerate(self, all, each) +} + +func goArrayDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { + if name == "length" { + return self.runtime.typeErrorResult(throw) + } else if index := stringToArrayIndex(name); index >= 0 { + object := self.value.(*_goArrayObject) + if object.writable { + if self.value.(*_goArrayObject).setValue(index, descriptor.value.(Value)) { + return true + } + } + return self.runtime.typeErrorResult(throw) + } + return objectDefineOwnProperty(self, name, descriptor, throw) +} + +func goArrayDelete(self *_object, name string, throw bool) bool { + // length + if name == "length" { + return self.runtime.typeErrorResult(throw) + } + + // .0, .1, .2, ... + index := stringToArrayIndex(name) + if index >= 0 { + object := self.value.(*_goArrayObject) + if object.writable { + indexValue, exists := object.getValue(index) + if exists { + indexValue.Set(reflect.Zero(reflect.Indirect(object.value).Type().Elem())) + return true + } + } + return self.runtime.typeErrorResult(throw) + } + + return self.delete(name, throw) +} diff --git a/vendor/github.com/robertkrimen/otto/type_go_map.go b/vendor/github.com/robertkrimen/otto/type_go_map.go new file mode 100644 index 0000000..542a2c2 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_go_map.go @@ -0,0 +1,87 @@ +package otto + +import ( + "reflect" +) + +func (runtime *_runtime) newGoMapObject(value reflect.Value) *_object { + self := runtime.newObject() + self.class = "Object" // TODO Should this be something else? + self.objectClass = _classGoMap + self.value = _newGoMapObject(value) + return self +} + +type _goMapObject struct { + value reflect.Value + keyKind reflect.Kind + valueKind reflect.Kind +} + +func _newGoMapObject(value reflect.Value) *_goMapObject { + if value.Kind() != reflect.Map { + dbgf("%/panic//%@: %v != reflect.Map", value.Kind()) + } + self := &_goMapObject{ + value: value, + keyKind: value.Type().Key().Kind(), + valueKind: value.Type().Elem().Kind(), + } + return self +} + +func (self _goMapObject) toKey(name string) reflect.Value { + reflectValue, err := stringToReflectValue(name, self.keyKind) + if err != nil { + panic(err) + } + return reflectValue +} + +func (self _goMapObject) toValue(value Value) reflect.Value { + reflectValue, err := value.toReflectValue(self.valueKind) + if err != nil { + panic(err) + } + return reflectValue +} + +func goMapGetOwnProperty(self *_object, name string) *_property { + object := self.value.(*_goMapObject) + value := object.value.MapIndex(object.toKey(name)) + if value.IsValid() { + return &_property{self.runtime.toValue(value.Interface()), 0111} + } + + return nil +} + +func goMapEnumerate(self *_object, all bool, each func(string) bool) { + object := self.value.(*_goMapObject) + keys := object.value.MapKeys() + for _, key := range keys { + if !each(key.String()) { + return + } + } +} + +func goMapDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { + object := self.value.(*_goMapObject) + // TODO ...or 0222 + if descriptor.mode != 0111 { + return self.runtime.typeErrorResult(throw) + } + if !descriptor.isDataDescriptor() { + return self.runtime.typeErrorResult(throw) + } + object.value.SetMapIndex(object.toKey(name), object.toValue(descriptor.value.(Value))) + return true +} + +func goMapDelete(self *_object, name string, throw bool) bool { + object := self.value.(*_goMapObject) + object.value.SetMapIndex(object.toKey(name), reflect.Value{}) + // FIXME + return true +} diff --git a/vendor/github.com/robertkrimen/otto/type_go_slice.go b/vendor/github.com/robertkrimen/otto/type_go_slice.go new file mode 100644 index 0000000..7143531 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_go_slice.go @@ -0,0 +1,118 @@ +package otto + +import ( + "reflect" + "strconv" +) + +func (runtime *_runtime) newGoSliceObject(value reflect.Value) *_object { + self := runtime.newObject() + self.class = "GoArray" // TODO GoSlice? + self.objectClass = _classGoSlice + self.value = _newGoSliceObject(value) + return self +} + +type _goSliceObject struct { + value reflect.Value +} + +func _newGoSliceObject(value reflect.Value) *_goSliceObject { + self := &_goSliceObject{ + value: value, + } + return self +} + +func (self _goSliceObject) getValue(index int64) (reflect.Value, bool) { + if index < int64(self.value.Len()) { + return self.value.Index(int(index)), true + } + return reflect.Value{}, false +} + +func (self _goSliceObject) setValue(index int64, value Value) bool { + indexValue, exists := self.getValue(index) + if !exists { + return false + } + reflectValue, err := value.toReflectValue(self.value.Type().Elem().Kind()) + if err != nil { + panic(err) + } + indexValue.Set(reflectValue) + return true +} + +func goSliceGetOwnProperty(self *_object, name string) *_property { + // length + if name == "length" { + return &_property{ + value: toValue(self.value.(*_goSliceObject).value.Len()), + mode: 0, + } + } + + // .0, .1, .2, ... + index := stringToArrayIndex(name) + if index >= 0 { + value := Value{} + reflectValue, exists := self.value.(*_goSliceObject).getValue(index) + if exists { + value = self.runtime.toValue(reflectValue.Interface()) + } + return &_property{ + value: value, + mode: 0110, + } + } + + return objectGetOwnProperty(self, name) +} + +func goSliceEnumerate(self *_object, all bool, each func(string) bool) { + object := self.value.(*_goSliceObject) + // .0, .1, .2, ... + + for index, length := 0, object.value.Len(); index < length; index++ { + name := strconv.FormatInt(int64(index), 10) + if !each(name) { + return + } + } + + objectEnumerate(self, all, each) +} + +func goSliceDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool { + if name == "length" { + return self.runtime.typeErrorResult(throw) + } else if index := stringToArrayIndex(name); index >= 0 { + if self.value.(*_goSliceObject).setValue(index, descriptor.value.(Value)) { + return true + } + return self.runtime.typeErrorResult(throw) + } + return objectDefineOwnProperty(self, name, descriptor, throw) +} + +func goSliceDelete(self *_object, name string, throw bool) bool { + // length + if name == "length" { + return self.runtime.typeErrorResult(throw) + } + + // .0, .1, .2, ... + index := stringToArrayIndex(name) + if index >= 0 { + object := self.value.(*_goSliceObject) + indexValue, exists := object.getValue(index) + if exists { + indexValue.Set(reflect.Zero(object.value.Type().Elem())) + return true + } + return self.runtime.typeErrorResult(throw) + } + + return self.delete(name, throw) +} diff --git a/vendor/github.com/robertkrimen/otto/type_go_struct.go b/vendor/github.com/robertkrimen/otto/type_go_struct.go new file mode 100644 index 0000000..608ac66 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_go_struct.go @@ -0,0 +1,146 @@ +package otto + +import ( + "encoding/json" + "reflect" +) + +// FIXME Make a note about not being able to modify a struct unless it was +// passed as a pointer-to: &struct{ ... } +// This seems to be a limitation of the reflect package. +// This goes for the other Go constructs too. +// I guess we could get around it by either: +// 1. Creating a new struct every time +// 2. Creating an addressable? struct in the constructor + +func (runtime *_runtime) newGoStructObject(value reflect.Value) *_object { + self := runtime.newObject() + self.class = "Object" // TODO Should this be something else? + self.objectClass = _classGoStruct + self.value = _newGoStructObject(value) + return self +} + +type _goStructObject struct { + value reflect.Value +} + +func _newGoStructObject(value reflect.Value) *_goStructObject { + if reflect.Indirect(value).Kind() != reflect.Struct { + dbgf("%/panic//%@: %v != reflect.Struct", value.Kind()) + } + self := &_goStructObject{ + value: value, + } + return self +} + +func (self _goStructObject) getValue(name string) reflect.Value { + if validGoStructName(name) { + // Do not reveal hidden or unexported fields + if field := reflect.Indirect(self.value).FieldByName(name); (field != reflect.Value{}) { + return field + } + + if method := self.value.MethodByName(name); (method != reflect.Value{}) { + return method + } + } + + return reflect.Value{} +} + +func (self _goStructObject) field(name string) (reflect.StructField, bool) { + return reflect.Indirect(self.value).Type().FieldByName(name) +} + +func (self _goStructObject) method(name string) (reflect.Method, bool) { + return reflect.Indirect(self.value).Type().MethodByName(name) +} + +func (self _goStructObject) setValue(name string, value Value) bool { + field, exists := self.field(name) + if !exists { + return false + } + fieldValue := self.getValue(name) + reflectValue, err := value.toReflectValue(field.Type.Kind()) + if err != nil { + panic(err) + } + fieldValue.Set(reflectValue) + + return true +} + +func goStructGetOwnProperty(self *_object, name string) *_property { + object := self.value.(*_goStructObject) + value := object.getValue(name) + if value.IsValid() { + return &_property{self.runtime.toValue(value.Interface()), 0110} + } + + return objectGetOwnProperty(self, name) +} + +func validGoStructName(name string) bool { + if name == "" { + return false + } + return 'A' <= name[0] && name[0] <= 'Z' // TODO What about Unicode? +} + +func goStructEnumerate(self *_object, all bool, each func(string) bool) { + object := self.value.(*_goStructObject) + + // Enumerate fields + for index := 0; index < reflect.Indirect(object.value).NumField(); index++ { + name := reflect.Indirect(object.value).Type().Field(index).Name + if validGoStructName(name) { + if !each(name) { + return + } + } + } + + // Enumerate methods + for index := 0; index < object.value.NumMethod(); index++ { + name := object.value.Type().Method(index).Name + if validGoStructName(name) { + if !each(name) { + return + } + } + } + + objectEnumerate(self, all, each) +} + +func goStructCanPut(self *_object, name string) bool { + object := self.value.(*_goStructObject) + value := object.getValue(name) + if value.IsValid() { + return true + } + + return objectCanPut(self, name) +} + +func goStructPut(self *_object, name string, value Value, throw bool) { + object := self.value.(*_goStructObject) + if object.setValue(name, value) { + return + } + + objectPut(self, name, value, throw) +} + +func goStructMarshalJSON(self *_object) json.Marshaler { + object := self.value.(*_goStructObject) + goValue := reflect.Indirect(object.value).Interface() + switch marshaler := goValue.(type) { + case json.Marshaler: + return marshaler + } + return nil +} diff --git a/vendor/github.com/robertkrimen/otto/type_number.go b/vendor/github.com/robertkrimen/otto/type_number.go new file mode 100644 index 0000000..28de444 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_number.go @@ -0,0 +1,5 @@ +package otto + +func (runtime *_runtime) newNumberObject(value Value) *_object { + return runtime.newPrimitiveObject("Number", value.numberValue()) +} diff --git a/vendor/github.com/robertkrimen/otto/type_reference.go b/vendor/github.com/robertkrimen/otto/type_reference.go new file mode 100644 index 0000000..fd770c6 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_reference.go @@ -0,0 +1,103 @@ +package otto + +type _reference interface { + invalid() bool // IsUnresolvableReference + getValue() Value // getValue + putValue(Value) string // PutValue + delete() bool +} + +// PropertyReference + +type _propertyReference struct { + name string + strict bool + base *_object + runtime *_runtime + at _at +} + +func newPropertyReference(rt *_runtime, base *_object, name string, strict bool, at _at) *_propertyReference { + return &_propertyReference{ + runtime: rt, + name: name, + strict: strict, + base: base, + at: at, + } +} + +func (self *_propertyReference) invalid() bool { + return self.base == nil +} + +func (self *_propertyReference) getValue() Value { + if self.base == nil { + panic(self.runtime.panicReferenceError("'%s' is not defined", self.name, self.at)) + } + return self.base.get(self.name) +} + +func (self *_propertyReference) putValue(value Value) string { + if self.base == nil { + return self.name + } + self.base.put(self.name, value, self.strict) + return "" +} + +func (self *_propertyReference) delete() bool { + if self.base == nil { + // TODO Throw an error if strict + return true + } + return self.base.delete(self.name, self.strict) +} + +// ArgumentReference + +func newArgumentReference(runtime *_runtime, base *_object, name string, strict bool, at _at) *_propertyReference { + if base == nil { + panic(hereBeDragons()) + } + return newPropertyReference(runtime, base, name, strict, at) +} + +type _stashReference struct { + name string + strict bool + base _stash +} + +func (self *_stashReference) invalid() bool { + return false // The base (an environment) will never be nil +} + +func (self *_stashReference) getValue() Value { + return self.base.getBinding(self.name, self.strict) +} + +func (self *_stashReference) putValue(value Value) string { + self.base.setValue(self.name, value, self.strict) + return "" +} + +func (self *_stashReference) 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(runtime *_runtime, stash _stash, name string, strict bool, at _at) _reference { + if stash == nil { + return newPropertyReference(runtime, nil, name, strict, at) + } + if stash.hasBinding(name) { + return stash.newReference(name, strict, at) + } + return getIdentifierReference(runtime, stash.outer(), name, strict, at) +} diff --git a/vendor/github.com/robertkrimen/otto/type_regexp.go b/vendor/github.com/robertkrimen/otto/type_regexp.go new file mode 100644 index 0000000..57fe316 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_regexp.go @@ -0,0 +1,146 @@ +package otto + +import ( + "fmt" + "regexp" + "unicode/utf8" + + "github.com/robertkrimen/otto/parser" +) + +type _regExpObject struct { + regularExpression *regexp.Regexp + global bool + ignoreCase bool + multiline bool + source string + flags string +} + +func (runtime *_runtime) newRegExpObject(pattern string, flags string) *_object { + self := runtime.newObject() + self.class = "RegExp" + + global := false + ignoreCase := false + multiline := false + re2flags := "" + + // TODO Maybe clean up the panicking here... TypeError, SyntaxError, ? + + for _, chr := range flags { + switch chr { + case 'g': + if global { + panic(runtime.panicSyntaxError("newRegExpObject: %s %s", pattern, flags)) + } + global = true + case 'm': + if multiline { + panic(runtime.panicSyntaxError("newRegExpObject: %s %s", pattern, flags)) + } + multiline = true + re2flags += "m" + case 'i': + if ignoreCase { + panic(runtime.panicSyntaxError("newRegExpObject: %s %s", pattern, flags)) + } + ignoreCase = true + re2flags += "i" + } + } + + re2pattern, err := parser.TransformRegExp(pattern) + if err != nil { + panic(runtime.panicTypeError("Invalid regular expression: %s", err.Error())) + } + if len(re2flags) > 0 { + re2pattern = fmt.Sprintf("(?%s:%s)", re2flags, re2pattern) + } + + regularExpression, err := regexp.Compile(re2pattern) + if err != nil { + panic(runtime.panicSyntaxError("Invalid regular expression: %s", err.Error()[22:])) + } + + self.value = _regExpObject{ + regularExpression: regularExpression, + global: global, + ignoreCase: ignoreCase, + multiline: multiline, + source: pattern, + flags: flags, + } + self.defineProperty("global", toValue_bool(global), 0, false) + self.defineProperty("ignoreCase", toValue_bool(ignoreCase), 0, false) + self.defineProperty("multiline", toValue_bool(multiline), 0, false) + self.defineProperty("lastIndex", toValue_int(0), 0100, false) + self.defineProperty("source", toValue_string(pattern), 0, false) + return self +} + +func (self *_object) regExpValue() _regExpObject { + value, _ := self.value.(_regExpObject) + return value +} + +func execRegExp(this *_object, target string) (match bool, result []int) { + if this.class != "RegExp" { + panic(this.runtime.panicTypeError("Calling RegExp.exec on a non-RegExp object")) + } + lastIndex := this.get("lastIndex").number().int64 + index := lastIndex + global := this.get("global").bool() + if !global { + index = 0 + } + if 0 > index || index > int64(len(target)) { + } else { + result = this.regExpValue().regularExpression.FindStringSubmatchIndex(target[index:]) + } + if result == nil { + //this.defineProperty("lastIndex", toValue_(0), 0111, true) + this.put("lastIndex", toValue_int(0), true) + return // !match + } + match = true + startIndex := index + endIndex := int(lastIndex) + result[1] + // We do this shift here because the .FindStringSubmatchIndex above + // was done on a local subordinate slice of the string, not the whole string + for index, _ := range result { + result[index] += int(startIndex) + } + if global { + //this.defineProperty("lastIndex", toValue_(endIndex), 0111, true) + this.put("lastIndex", toValue_int(endIndex), true) + } + return // match +} + +func execResultToArray(runtime *_runtime, target string, result []int) *_object { + captureCount := len(result) / 2 + valueArray := make([]Value, captureCount) + for index := 0; index < captureCount; index++ { + offset := 2 * index + if result[offset] != -1 { + valueArray[index] = toValue_string(target[result[offset]:result[offset+1]]) + } else { + valueArray[index] = Value{} + } + } + matchIndex := result[0] + if matchIndex != 0 { + matchIndex = 0 + // Find the rune index in the string, not the byte index + for index := 0; index < result[0]; { + _, size := utf8.DecodeRuneInString(target[index:]) + matchIndex += 1 + index += size + } + } + match := runtime.newArrayOf(valueArray) + match.defineProperty("input", toValue_string(target), 0111, false) + match.defineProperty("index", toValue_int(matchIndex), 0111, false) + return match +} diff --git a/vendor/github.com/robertkrimen/otto/type_string.go b/vendor/github.com/robertkrimen/otto/type_string.go new file mode 100644 index 0000000..ef3afa4 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/type_string.go @@ -0,0 +1,112 @@ +package otto + +import ( + "strconv" + "unicode/utf8" +) + +type _stringObject interface { + Length() int + At(int) rune + String() string +} + +type _stringASCII string + +func (str _stringASCII) Length() int { + return len(str) +} + +func (str _stringASCII) At(at int) rune { + return rune(str[at]) +} + +func (str _stringASCII) String() string { + return string(str) +} + +type _stringWide struct { + string string + length int + runes []rune +} + +func (str _stringWide) Length() int { + return str.length +} + +func (str _stringWide) At(at int) rune { + if str.runes == nil { + str.runes = []rune(str.string) + } + return str.runes[at] +} + +func (str _stringWide) String() string { + return str.string +} + +func _newStringObject(str string) _stringObject { + for i := 0; i < len(str); i++ { + if str[i] >= utf8.RuneSelf { + goto wide + } + } + + return _stringASCII(str) + +wide: + return &_stringWide{ + string: str, + length: utf8.RuneCountInString(str), + } +} + +func stringAt(str _stringObject, index int) rune { + if 0 <= index && index < str.Length() { + return str.At(index) + } + return utf8.RuneError +} + +func (runtime *_runtime) newStringObject(value Value) *_object { + str := _newStringObject(value.string()) + + self := runtime.newClassObject("String") + self.defineProperty("length", toValue_int(str.Length()), 0, false) + self.objectClass = _classString + self.value = str + return self +} + +func (self *_object) stringValue() _stringObject { + if str, ok := self.value.(_stringObject); ok { + return str + } + return nil +} + +func stringEnumerate(self *_object, all bool, each func(string) bool) { + if str := self.stringValue(); str != nil { + length := str.Length() + for index := 0; index < length; index++ { + if !each(strconv.FormatInt(int64(index), 10)) { + return + } + } + } + objectEnumerate(self, all, each) +} + +func stringGetOwnProperty(self *_object, name string) *_property { + if property := objectGetOwnProperty(self, name); property != nil { + return property + } + // TODO Test a string of length >= +int32 + 1? + if index := stringToArrayIndex(name); index >= 0 { + if chr := stringAt(self.stringValue(), int(index)); chr != utf8.RuneError { + return &_property{toValue_string(string(chr)), 0} + } + } + return nil +} diff --git a/vendor/github.com/robertkrimen/otto/value.go b/vendor/github.com/robertkrimen/otto/value.go new file mode 100644 index 0000000..05d61dd --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/value.go @@ -0,0 +1,989 @@ +package otto + +import ( + "fmt" + "math" + "reflect" + "strconv" + "unicode/utf16" +) + +type _valueKind int + +const ( + valueUndefined _valueKind = iota + valueNull + valueNumber + valueString + valueBoolean + valueObject + + // These are invalid outside of the runtime + valueEmpty + valueResult + valueReference +) + +// Value is the representation of a JavaScript value. +type Value struct { + kind _valueKind + value interface{} +} + +func (vl Value) safe() bool { + return vl.kind < valueEmpty +} + +var ( + emptyValue = Value{kind: valueEmpty} + nullValue = Value{kind: valueNull} + falseValue = Value{kind: valueBoolean, value: false} + trueValue = Value{kind: valueBoolean, value: true} +) + +// 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 should use Otto.ToValue instead. +func ToValue(value interface{}) (Value, error) { + result := Value{} + err := catchPanic(func() { + result = toValue(value) + }) + return result, err +} + +func (value Value) isEmpty() bool { + return value.kind == valueEmpty +} + +// Undefined + +// UndefinedValue will return a Value representing undefined. +func UndefinedValue() Value { + return Value{} +} + +// IsDefined will return false if the value is undefined, and true otherwise. +func (value Value) IsDefined() bool { + return value.kind != valueUndefined +} + +// IsUndefined will return true if the value is undefined, and false otherwise. +func (value Value) IsUndefined() bool { + return value.kind == valueUndefined +} + +// NullValue will return a Value representing null. +func NullValue() Value { + return Value{kind: valueNull} +} + +// IsNull will return true if the value is null, and false otherwise. +func (value Value) IsNull() bool { + return value.kind == valueNull +} + +// --- + +func (value Value) isCallable() bool { + switch value := value.value.(type) { + case *_object: + return value.isCall() + } + return false +} + +// Call the value as a function with the given this value and argument list and +// return the result of invocation. It is essentially equivalent to: +// +// value.apply(thisValue, argumentList) +// +// An undefined value and an error will result if: +// +// 1. There is an error during conversion of the argument list +// 2. The value is not actually a function +// 3. An (uncaught) exception is thrown +// +func (value Value) Call(this Value, argumentList ...interface{}) (Value, error) { + result := Value{} + err := catchPanic(func() { + // FIXME + result = value.call(nil, this, argumentList...) + }) + if !value.safe() { + value = Value{} + } + return result, err +} + +func (value Value) call(rt *_runtime, this Value, argumentList ...interface{}) Value { + switch function := value.value.(type) { + case *_object: + return function.call(this, function.runtime.toValueArray(argumentList...), false, nativeFrame) + } + if rt == nil { + panic("FIXME TypeError") + } + panic(rt.panicTypeError()) +} + +func (value Value) constructSafe(rt *_runtime, this Value, argumentList ...interface{}) (Value, error) { + result := Value{} + err := catchPanic(func() { + result = value.construct(rt, this, argumentList...) + }) + return result, err +} + +func (value Value) construct(rt *_runtime, this Value, argumentList ...interface{}) Value { + switch fn := value.value.(type) { + case *_object: + return fn.construct(fn.runtime.toValueArray(argumentList...)) + } + if rt == nil { + panic("FIXME TypeError") + } + panic(rt.panicTypeError()) +} + +// IsPrimitive will return true if value is a primitive (any kind of primitive). +func (value Value) IsPrimitive() bool { + return !value.IsObject() +} + +// IsBoolean will return true if value is a boolean (primitive). +func (value Value) IsBoolean() bool { + return value.kind == valueBoolean +} + +// IsNumber will return true if value is a number (primitive). +func (value Value) IsNumber() bool { + return value.kind == valueNumber +} + +// IsNaN will return true if value is NaN (or would convert to NaN). +func (value Value) IsNaN() bool { + switch value := value.value.(type) { + case float64: + return math.IsNaN(value) + case float32: + return math.IsNaN(float64(value)) + case int, int8, int32, int64: + return false + case uint, uint8, uint32, uint64: + return false + } + + return math.IsNaN(value.float64()) +} + +// IsString will return true if value is a string (primitive). +func (value Value) IsString() bool { + return value.kind == valueString +} + +// IsObject will return true if value is an object. +func (value Value) IsObject() bool { + return value.kind == valueObject +} + +// IsFunction will return true if value is a function. +func (value Value) IsFunction() bool { + if value.kind != valueObject { + return false + } + return value.value.(*_object).class == "Function" +} + +// Class will return the class string of the value or the empty string if value is not an object. +// +// The return value will (generally) be one of: +// +// Object +// Function +// Array +// String +// Number +// Boolean +// Date +// RegExp +// +func (value Value) Class() string { + if value.kind != valueObject { + return "" + } + return value.value.(*_object).class +} + +func (value Value) isArray() bool { + if value.kind != valueObject { + return false + } + return isArray(value.value.(*_object)) +} + +func (value Value) isStringObject() bool { + if value.kind != valueObject { + return false + } + return value.value.(*_object).class == "String" +} + +func (value Value) isBooleanObject() bool { + if value.kind != valueObject { + return false + } + return value.value.(*_object).class == "Boolean" +} + +func (value Value) isNumberObject() bool { + if value.kind != valueObject { + return false + } + return value.value.(*_object).class == "Number" +} + +func (value Value) isDate() bool { + if value.kind != valueObject { + return false + } + return value.value.(*_object).class == "Date" +} + +func (value Value) isRegExp() bool { + if value.kind != valueObject { + return false + } + return value.value.(*_object).class == "RegExp" +} + +func (value Value) isError() bool { + if value.kind != valueObject { + return false + } + return value.value.(*_object).class == "Error" +} + +// --- + +func toValue_reflectValuePanic(value interface{}, kind reflect.Kind) { + // FIXME? + switch kind { + case reflect.Struct: + panic(newError(nil, "TypeError", "invalid value (struct): missing runtime: %v (%T)", value, value)) + case reflect.Map: + panic(newError(nil, "TypeError", "invalid value (map): missing runtime: %v (%T)", value, value)) + case reflect.Slice: + panic(newError(nil, "TypeError", "invalid value (slice): missing runtime: %v (%T)", value, value)) + } +} + +func toValue(value interface{}) Value { + switch value := value.(type) { + case Value: + return value + case bool: + return Value{valueBoolean, value} + case int: + return Value{valueNumber, value} + case int8: + return Value{valueNumber, value} + case int16: + return Value{valueNumber, value} + case int32: + return Value{valueNumber, value} + case int64: + return Value{valueNumber, value} + case uint: + return Value{valueNumber, value} + case uint8: + return Value{valueNumber, value} + case uint16: + return Value{valueNumber, value} + case uint32: + return Value{valueNumber, value} + case uint64: + return Value{valueNumber, value} + case float32: + return Value{valueNumber, float64(value)} + case float64: + return Value{valueNumber, value} + case []uint16: + return Value{valueString, value} + case string: + return Value{valueString, value} + // A rune is actually an int32, which is handled above + case *_object: + return Value{valueObject, value} + case *Object: + return Value{valueObject, value.object} + case Object: + return Value{valueObject, value.object} + case _reference: // reference is an interface (already a pointer) + return Value{valueReference, value} + case _result: + return Value{valueResult, value} + case nil: + // TODO Ugh. + return Value{} + case reflect.Value: + for value.Kind() == reflect.Ptr { + // We were given a pointer, so we'll drill down until we get a non-pointer + // + // These semantics might change if we want to start supporting pointers to values transparently + // (It would be best not to depend on this behavior) + // FIXME: UNDEFINED + if value.IsNil() { + return Value{} + } + value = value.Elem() + } + switch value.Kind() { + case reflect.Bool: + return Value{valueBoolean, bool(value.Bool())} + case reflect.Int: + return Value{valueNumber, int(value.Int())} + case reflect.Int8: + return Value{valueNumber, int8(value.Int())} + case reflect.Int16: + return Value{valueNumber, int16(value.Int())} + case reflect.Int32: + return Value{valueNumber, int32(value.Int())} + case reflect.Int64: + return Value{valueNumber, int64(value.Int())} + case reflect.Uint: + return Value{valueNumber, uint(value.Uint())} + case reflect.Uint8: + return Value{valueNumber, uint8(value.Uint())} + case reflect.Uint16: + return Value{valueNumber, uint16(value.Uint())} + case reflect.Uint32: + return Value{valueNumber, uint32(value.Uint())} + case reflect.Uint64: + return Value{valueNumber, uint64(value.Uint())} + case reflect.Float32: + return Value{valueNumber, float32(value.Float())} + case reflect.Float64: + return Value{valueNumber, float64(value.Float())} + case reflect.String: + return Value{valueString, string(value.String())} + default: + toValue_reflectValuePanic(value.Interface(), value.Kind()) + } + default: + return toValue(reflect.ValueOf(value)) + } + // FIXME? + panic(newError(nil, "TypeError", "invalid value: %v (%T)", value, value)) +} + +// String will return the value as a string. +// +// This method will make return the empty string if there is an error. +func (value Value) String() string { + result := "" + catchPanic(func() { + result = value.string() + }) + return result +} + +// ToBoolean will convert the value to a boolean (bool). +// +// ToValue(0).ToBoolean() => false +// ToValue("").ToBoolean() => false +// ToValue(true).ToBoolean() => true +// ToValue(1).ToBoolean() => true +// ToValue("Nothing happens").ToBoolean() => true +// +// If there is an error during the conversion process (like an uncaught exception), then the result will be false and an error. +func (value Value) ToBoolean() (bool, error) { + result := false + err := catchPanic(func() { + result = value.bool() + }) + return result, err +} + +func (value Value) numberValue() Value { + if value.kind == valueNumber { + return value + } + return Value{valueNumber, value.float64()} +} + +// ToFloat will convert the value to a number (float64). +// +// ToValue(0).ToFloat() => 0. +// ToValue(1.1).ToFloat() => 1.1 +// ToValue("11").ToFloat() => 11. +// +// If there is an error during the conversion process (like an uncaught exception), then the result will be 0 and an error. +func (value Value) ToFloat() (float64, error) { + result := float64(0) + err := catchPanic(func() { + result = value.float64() + }) + return result, err +} + +// ToInteger will convert the value to a number (int64). +// +// ToValue(0).ToInteger() => 0 +// ToValue(1.1).ToInteger() => 1 +// ToValue("11").ToInteger() => 11 +// +// If there is an error during the conversion process (like an uncaught exception), then the result will be 0 and an error. +func (value Value) ToInteger() (int64, error) { + result := int64(0) + err := catchPanic(func() { + result = value.number().int64 + }) + return result, err +} + +// ToString will convert the value to a string (string). +// +// ToValue(0).ToString() => "0" +// ToValue(false).ToString() => "false" +// ToValue(1.1).ToString() => "1.1" +// ToValue("11").ToString() => "11" +// ToValue('Nothing happens.').ToString() => "Nothing happens." +// +// If there is an error during the conversion process (like an uncaught exception), then the result will be the empty string ("") and an error. +func (value Value) ToString() (string, error) { + result := "" + err := catchPanic(func() { + result = value.string() + }) + return result, err +} + +func (value Value) _object() *_object { + switch value := value.value.(type) { + case *_object: + return value + } + return nil +} + +// Object will return the object of the value, or nil if value is not an object. +// +// This method will not do any implicit conversion. For example, calling this method on a string primitive value will not return a String object. +func (value Value) Object() *Object { + switch object := value.value.(type) { + case *_object: + return _newObject(object, value) + } + return nil +} + +func (value Value) reference() _reference { + switch value := value.value.(type) { + case _reference: + return value + } + return nil +} + +func (value Value) resolve() Value { + switch value := value.value.(type) { + case _reference: + return value.getValue() + } + return value +} + +var ( + __NaN__ float64 = math.NaN() + __PositiveInfinity__ float64 = math.Inf(+1) + __NegativeInfinity__ float64 = math.Inf(-1) + __PositiveZero__ float64 = 0 + __NegativeZero__ float64 = math.Float64frombits(0 | (1 << 63)) +) + +func positiveInfinity() float64 { + return __PositiveInfinity__ +} + +func negativeInfinity() float64 { + return __NegativeInfinity__ +} + +func positiveZero() float64 { + return __PositiveZero__ +} + +func negativeZero() float64 { + return __NegativeZero__ +} + +// NaNValue will return a value representing NaN. +// +// It is equivalent to: +// +// ToValue(math.NaN()) +// +func NaNValue() Value { + return Value{valueNumber, __NaN__} +} + +func positiveInfinityValue() Value { + return Value{valueNumber, __PositiveInfinity__} +} + +func negativeInfinityValue() Value { + return Value{valueNumber, __NegativeInfinity__} +} + +func positiveZeroValue() Value { + return Value{valueNumber, __PositiveZero__} +} + +func negativeZeroValue() Value { + return Value{valueNumber, __NegativeZero__} +} + +// TrueValue will return a value representing true. +// +// It is equivalent to: +// +// ToValue(true) +// +func TrueValue() Value { + return Value{valueBoolean, true} +} + +// FalseValue will return a value representing false. +// +// It is equivalent to: +// +// ToValue(false) +// +func FalseValue() Value { + return Value{valueBoolean, false} +} + +func sameValue(x Value, y Value) bool { + if x.kind != y.kind { + return false + } + result := false + switch x.kind { + case valueUndefined, valueNull: + result = true + case valueNumber: + x := x.float64() + y := y.float64() + if math.IsNaN(x) && math.IsNaN(y) { + result = true + } else { + result = x == y + if result && x == 0 { + // Since +0 != -0 + result = math.Signbit(x) == math.Signbit(y) + } + } + case valueString: + result = x.string() == y.string() + case valueBoolean: + result = x.bool() == y.bool() + case valueObject: + result = x._object() == y._object() + default: + panic(hereBeDragons()) + } + + return result +} + +func strictEqualityComparison(x Value, y Value) bool { + if x.kind != y.kind { + return false + } + result := false + switch x.kind { + case valueUndefined, valueNull: + result = true + case valueNumber: + x := x.float64() + y := y.float64() + if math.IsNaN(x) && math.IsNaN(y) { + result = false + } else { + result = x == y + } + case valueString: + result = x.string() == y.string() + case valueBoolean: + result = x.bool() == y.bool() + case valueObject: + result = x._object() == y._object() + default: + panic(hereBeDragons()) + } + + return result +} + +// Export will attempt to convert the value to a Go representation +// and return it via an interface{} kind. +// +// Export returns an error, but it will always be nil. It is present +// for backwards compatibility. +// +// If a reasonable conversion is not possible, then the original +// value is returned. +// +// undefined -> nil (FIXME?: Should be Value{}) +// null -> nil +// boolean -> bool +// number -> A number type (int, float32, uint64, ...) +// string -> string +// Array -> []interface{} +// Object -> map[string]interface{} +// +func (self Value) Export() (interface{}, error) { + return self.export(), nil +} + +func (self Value) export() interface{} { + + switch self.kind { + case valueUndefined: + return nil + case valueNull: + return nil + case valueNumber, valueBoolean: + return self.value + case valueString: + switch value := self.value.(type) { + case string: + return value + case []uint16: + return string(utf16.Decode(value)) + } + case valueObject: + object := self._object() + switch value := object.value.(type) { + case *_goStructObject: + return value.value.Interface() + case *_goMapObject: + return value.value.Interface() + case *_goArrayObject: + return value.value.Interface() + case *_goSliceObject: + return value.value.Interface() + } + if object.class == "Array" { + result := make([]interface{}, 0) + lengthValue := object.get("length") + length := lengthValue.value.(uint32) + for index := uint32(0); index < length; index += 1 { + name := strconv.FormatInt(int64(index), 10) + if !object.hasProperty(name) { + continue + } + value := object.get(name) + result = append(result, value.export()) + } + return result + } else { + result := make(map[string]interface{}) + // TODO Should we export everything? Or just what is enumerable? + object.enumerate(false, func(name string) bool { + value := object.get(name) + if value.IsDefined() { + result[name] = value.export() + } + return true + }) + return result + } + } + + if self.safe() { + return self + } + + return Value{} +} + +func (self Value) evaluateBreakContinue(labels []string) _resultKind { + result := self.value.(_result) + if result.kind == resultBreak || result.kind == resultContinue { + for _, label := range labels { + if label == result.target { + return result.kind + } + } + } + return resultReturn +} + +func (self Value) evaluateBreak(labels []string) _resultKind { + result := self.value.(_result) + if result.kind == resultBreak { + for _, label := range labels { + if label == result.target { + return result.kind + } + } + } + return resultReturn +} + +func (self Value) exportNative() interface{} { + + switch self.kind { + case valueUndefined: + return self + case valueNull: + return nil + case valueNumber, valueBoolean: + return self.value + case valueString: + switch value := self.value.(type) { + case string: + return value + case []uint16: + return string(utf16.Decode(value)) + } + case valueObject: + object := self._object() + switch value := object.value.(type) { + case *_goStructObject: + return value.value.Interface() + case *_goMapObject: + return value.value.Interface() + case *_goArrayObject: + return value.value.Interface() + case *_goSliceObject: + return value.value.Interface() + } + } + + return self +} + +// Make a best effort to return a reflect.Value corresponding to reflect.Kind, but +// fallback to just returning the Go value we have handy. +func (value Value) toReflectValue(kind reflect.Kind) (reflect.Value, error) { + switch kind { + case reflect.Bool: // Bool + return reflect.ValueOf(value.bool()), nil + case reflect.Int: // Int + // We convert to float64 here because converting to int64 will not tell us + // if a value is outside the range of int64 + tmp := toIntegerFloat(value) + if tmp < float_minInt || tmp > float_maxInt { + return reflect.Value{}, fmt.Errorf("RangeError: %f (%v) to int", tmp, value) + } else { + return reflect.ValueOf(int(tmp)), nil + } + case reflect.Int8: // Int8 + tmp := value.number().int64 + if tmp < int64_minInt8 || tmp > int64_maxInt8 { + return reflect.Value{}, fmt.Errorf("RangeError: %d (%v) to int8", tmp, value) + } else { + return reflect.ValueOf(int8(tmp)), nil + } + case reflect.Int16: // Int16 + tmp := value.number().int64 + if tmp < int64_minInt16 || tmp > int64_maxInt16 { + return reflect.Value{}, fmt.Errorf("RangeError: %d (%v) to int16", tmp, value) + } else { + return reflect.ValueOf(int16(tmp)), nil + } + case reflect.Int32: // Int32 + tmp := value.number().int64 + if tmp < int64_minInt32 || tmp > int64_maxInt32 { + return reflect.Value{}, fmt.Errorf("RangeError: %d (%v) to int32", tmp, value) + } else { + return reflect.ValueOf(int32(tmp)), nil + } + case reflect.Int64: // Int64 + // We convert to float64 here because converting to int64 will not tell us + // if a value is outside the range of int64 + tmp := toIntegerFloat(value) + if tmp < float_minInt64 || tmp > float_maxInt64 { + return reflect.Value{}, fmt.Errorf("RangeError: %f (%v) to int", tmp, value) + } else { + return reflect.ValueOf(int64(tmp)), nil + } + case reflect.Uint: // Uint + // We convert to float64 here because converting to int64 will not tell us + // if a value is outside the range of uint + tmp := toIntegerFloat(value) + if tmp < 0 || tmp > float_maxUint { + return reflect.Value{}, fmt.Errorf("RangeError: %f (%v) to uint", tmp, value) + } else { + return reflect.ValueOf(uint(tmp)), nil + } + case reflect.Uint8: // Uint8 + tmp := value.number().int64 + if tmp < 0 || tmp > int64_maxUint8 { + return reflect.Value{}, fmt.Errorf("RangeError: %d (%v) to uint8", tmp, value) + } else { + return reflect.ValueOf(uint8(tmp)), nil + } + case reflect.Uint16: // Uint16 + tmp := value.number().int64 + if tmp < 0 || tmp > int64_maxUint16 { + return reflect.Value{}, fmt.Errorf("RangeError: %d (%v) to uint16", tmp, value) + } else { + return reflect.ValueOf(uint16(tmp)), nil + } + case reflect.Uint32: // Uint32 + tmp := value.number().int64 + if tmp < 0 || tmp > int64_maxUint32 { + return reflect.Value{}, fmt.Errorf("RangeError: %d (%v) to uint32", tmp, value) + } else { + return reflect.ValueOf(uint32(tmp)), nil + } + case reflect.Uint64: // Uint64 + // We convert to float64 here because converting to int64 will not tell us + // if a value is outside the range of uint64 + tmp := toIntegerFloat(value) + if tmp < 0 || tmp > float_maxUint64 { + return reflect.Value{}, fmt.Errorf("RangeError: %f (%v) to uint64", tmp, value) + } else { + return reflect.ValueOf(uint64(tmp)), nil + } + case reflect.Float32: // Float32 + tmp := value.float64() + tmp1 := tmp + if 0 > tmp1 { + tmp1 = -tmp1 + } + if tmp1 < math.SmallestNonzeroFloat32 || tmp1 > math.MaxFloat32 { + return reflect.Value{}, fmt.Errorf("RangeError: %f (%v) to float32", tmp, value) + } else { + return reflect.ValueOf(float32(tmp)), nil + } + case reflect.Float64: // Float64 + value := value.float64() + return reflect.ValueOf(float64(value)), nil + case reflect.String: // String + return reflect.ValueOf(value.string()), nil + case reflect.Invalid: // Invalid + case reflect.Complex64: // FIXME? Complex64 + case reflect.Complex128: // FIXME? Complex128 + case reflect.Chan: // FIXME? Chan + case reflect.Func: // FIXME? Func + case reflect.Ptr: // FIXME? Ptr + case reflect.UnsafePointer: // FIXME? UnsafePointer + default: + switch value.kind { + case valueObject: + object := value._object() + switch vl := object.value.(type) { + case *_goStructObject: // Struct + return reflect.ValueOf(vl.value.Interface()), nil + case *_goMapObject: // Map + return reflect.ValueOf(vl.value.Interface()), nil + case *_goArrayObject: // Array + return reflect.ValueOf(vl.value.Interface()), nil + case *_goSliceObject: // Slice + return reflect.ValueOf(vl.value.Interface()), nil + } + return reflect.ValueOf(value.exportNative()), nil + case valueEmpty, valueResult, valueReference: + // These are invalid, and should panic + default: + return reflect.ValueOf(value.value), nil + } + } + + // FIXME Should this end up as a TypeError? + panic(fmt.Errorf("invalid conversion of %v (%v) to reflect.Kind: %v", value.kind, value, kind)) +} + +func stringToReflectValue(value string, kind reflect.Kind) (reflect.Value, error) { + switch kind { + case reflect.Bool: + value, err := strconv.ParseBool(value) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(value), nil + case reflect.Int: + value, err := strconv.ParseInt(value, 0, 0) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(int(value)), nil + case reflect.Int8: + value, err := strconv.ParseInt(value, 0, 8) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(int8(value)), nil + case reflect.Int16: + value, err := strconv.ParseInt(value, 0, 16) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(int16(value)), nil + case reflect.Int32: + value, err := strconv.ParseInt(value, 0, 32) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(int32(value)), nil + case reflect.Int64: + value, err := strconv.ParseInt(value, 0, 64) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(int64(value)), nil + case reflect.Uint: + value, err := strconv.ParseUint(value, 0, 0) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(uint(value)), nil + case reflect.Uint8: + value, err := strconv.ParseUint(value, 0, 8) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(uint8(value)), nil + case reflect.Uint16: + value, err := strconv.ParseUint(value, 0, 16) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(uint16(value)), nil + case reflect.Uint32: + value, err := strconv.ParseUint(value, 0, 32) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(uint32(value)), nil + case reflect.Uint64: + value, err := strconv.ParseUint(value, 0, 64) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(uint64(value)), nil + case reflect.Float32: + value, err := strconv.ParseFloat(value, 32) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(float32(value)), nil + case reflect.Float64: + value, err := strconv.ParseFloat(value, 64) + if err != nil { + return reflect.Value{}, err + } + return reflect.ValueOf(float64(value)), nil + case reflect.String: + return reflect.ValueOf(value), nil + } + + // FIXME This should end up as a TypeError? + panic(fmt.Errorf("invalid conversion of %q to reflect.Kind: %v", value, kind)) +} diff --git a/vendor/github.com/robertkrimen/otto/value_boolean.go b/vendor/github.com/robertkrimen/otto/value_boolean.go new file mode 100644 index 0000000..3040f41 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/value_boolean.go @@ -0,0 +1,40 @@ +package otto + +import ( + "fmt" + "math" + "reflect" +) + +func (value Value) bool() bool { + if value.kind == valueBoolean { + return value.value.(bool) + } + if value.IsUndefined() { + return false + } + if value.IsNull() { + return false + } + switch value := value.value.(type) { + case bool: + return value + case int, int8, int16, int32, int64: + return 0 != reflect.ValueOf(value).Int() + case uint, uint8, uint16, uint32, uint64: + return 0 != reflect.ValueOf(value).Uint() + case float32: + return 0 != value + case float64: + if math.IsNaN(value) || value == 0 { + return false + } + return true + case string: + return 0 != len(value) + } + if value.IsObject() { + return true + } + panic(fmt.Errorf("toBoolean(%T)", value.value)) +} diff --git a/vendor/github.com/robertkrimen/otto/value_number.go b/vendor/github.com/robertkrimen/otto/value_number.go new file mode 100644 index 0000000..54996c7 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/value_number.go @@ -0,0 +1,324 @@ +package otto + +import ( + "fmt" + "math" + "regexp" + "strconv" + "strings" +) + +var stringToNumberParseInteger = regexp.MustCompile(`^(?:0[xX])`) + +func parseNumber(value string) float64 { + value = strings.TrimSpace(value) + + if value == "" { + return 0 + } + + parseFloat := false + if strings.IndexRune(value, '.') != -1 { + parseFloat = true + } else if stringToNumberParseInteger.MatchString(value) { + parseFloat = false + } else { + parseFloat = true + } + + if parseFloat { + number, err := strconv.ParseFloat(value, 64) + if err != nil && err.(*strconv.NumError).Err != strconv.ErrRange { + return math.NaN() + } + return number + } + + number, err := strconv.ParseInt(value, 0, 64) + if err != nil { + return math.NaN() + } + return float64(number) +} + +func (value Value) float64() float64 { + switch value.kind { + case valueUndefined: + return math.NaN() + case valueNull: + return 0 + } + switch value := value.value.(type) { + case bool: + if value { + return 1 + } + return 0 + case int: + return float64(value) + case int8: + return float64(value) + case int16: + return float64(value) + case int32: + return float64(value) + case int64: + return float64(value) + case uint: + return float64(value) + case uint8: + return float64(value) + case uint16: + return float64(value) + case uint32: + return float64(value) + case uint64: + return float64(value) + case float64: + return value + case string: + return parseNumber(value) + case *_object: + return value.DefaultValue(defaultValueHintNumber).float64() + } + panic(fmt.Errorf("toFloat(%T)", value.value)) +} + +const ( + float_2_64 float64 = 18446744073709551616.0 + float_2_63 float64 = 9223372036854775808.0 + float_2_32 float64 = 4294967296.0 + float_2_31 float64 = 2147483648.0 + float_2_16 float64 = 65536.0 + integer_2_32 int64 = 4294967296 + integer_2_31 int64 = 2146483648 + sqrt1_2 float64 = math.Sqrt2 / 2 +) + +const ( + maxInt8 = math.MaxInt8 + minInt8 = math.MinInt8 + maxInt16 = math.MaxInt16 + minInt16 = math.MinInt16 + maxInt32 = math.MaxInt32 + minInt32 = math.MinInt32 + maxInt64 = math.MaxInt64 + minInt64 = math.MinInt64 + maxUint8 = math.MaxUint8 + maxUint16 = math.MaxUint16 + maxUint32 = math.MaxUint32 + maxUint64 = math.MaxUint64 + maxUint = ^uint(0) + minUint = 0 + maxInt = int(^uint(0) >> 1) + minInt = -maxInt - 1 + + // int64 + int64_maxInt int64 = int64(maxInt) + int64_minInt int64 = int64(minInt) + int64_maxInt8 int64 = math.MaxInt8 + int64_minInt8 int64 = math.MinInt8 + int64_maxInt16 int64 = math.MaxInt16 + int64_minInt16 int64 = math.MinInt16 + int64_maxInt32 int64 = math.MaxInt32 + int64_minInt32 int64 = math.MinInt32 + int64_maxUint8 int64 = math.MaxUint8 + int64_maxUint16 int64 = math.MaxUint16 + int64_maxUint32 int64 = math.MaxUint32 + + // float64 + float_maxInt float64 = float64(int(^uint(0) >> 1)) + float_minInt float64 = float64(int(-maxInt - 1)) + float_minUint float64 = float64(0) + float_maxUint float64 = float64(uint(^uint(0))) + float_minUint64 float64 = float64(0) + float_maxUint64 float64 = math.MaxUint64 + float_maxInt64 float64 = math.MaxInt64 + float_minInt64 float64 = math.MinInt64 +) + +func toIntegerFloat(value Value) float64 { + float := value.float64() + if math.IsInf(float, 0) { + } else if math.IsNaN(float) { + float = 0 + } else if float > 0 { + float = math.Floor(float) + } else { + float = math.Ceil(float) + } + return float +} + +type _numberKind int + +const ( + numberInteger _numberKind = iota // 3.0 => 3.0 + numberFloat // 3.14159 => 3.0, 1+2**63 > 2**63-1 + numberInfinity // Infinity => 2**63-1 + numberNaN // NaN => 0 +) + +type _number struct { + kind _numberKind + int64 int64 + float64 float64 +} + +// FIXME +// http://www.goinggo.net/2013/08/gustavos-ieee-754-brain-teaser.html +// http://bazaar.launchpad.net/~niemeyer/strepr/trunk/view/6/strepr.go#L160 +func (vl Value) number() (number _number) { + switch vl := vl.value.(type) { + case int8: + number.int64 = int64(vl) + return + case int16: + number.int64 = int64(vl) + return + case uint8: + number.int64 = int64(vl) + return + case uint16: + number.int64 = int64(vl) + return + case uint32: + number.int64 = int64(vl) + return + case int: + number.int64 = int64(vl) + return + case int64: + number.int64 = vl + return + } + + float := vl.float64() + if float == 0 { + return + } + + number.kind = numberFloat + number.float64 = float + + if math.IsNaN(float) { + number.kind = numberNaN + return + } + + if math.IsInf(float, 0) { + number.kind = numberInfinity + } + + if float >= float_maxInt64 { + number.int64 = math.MaxInt64 + return + } + + if float <= float_minInt64 { + number.int64 = math.MinInt64 + return + } + + integer := float64(0) + if float > 0 { + integer = math.Floor(float) + } else { + integer = math.Ceil(float) + } + + if float == integer { + number.kind = numberInteger + } + number.int64 = int64(float) + return +} + +// ECMA 262: 9.5 +func toInt32(value Value) int32 { + { + switch value := value.value.(type) { + case int8: + return int32(value) + case int16: + return int32(value) + case int32: + return value + } + } + floatValue := value.float64() + if math.IsNaN(floatValue) || math.IsInf(floatValue, 0) { + return 0 + } + if floatValue == 0 { // This will work for +0 & -0 + return 0 + } + remainder := math.Mod(floatValue, float_2_32) + if remainder > 0 { + remainder = math.Floor(remainder) + } else { + remainder = math.Ceil(remainder) + float_2_32 + } + if remainder > float_2_31 { + return int32(remainder - float_2_32) + } + return int32(remainder) +} + +func toUint32(value Value) uint32 { + { + switch value := value.value.(type) { + case int8: + return uint32(value) + case int16: + return uint32(value) + case uint8: + return uint32(value) + case uint16: + return uint32(value) + case uint32: + return value + } + } + floatValue := value.float64() + if math.IsNaN(floatValue) || math.IsInf(floatValue, 0) { + return 0 + } + if floatValue == 0 { + return 0 + } + remainder := math.Mod(floatValue, float_2_32) + if remainder > 0 { + remainder = math.Floor(remainder) + } else { + remainder = math.Ceil(remainder) + float_2_32 + } + return uint32(remainder) +} + +func toUint16(value Value) uint16 { + { + switch value := value.value.(type) { + case int8: + return uint16(value) + case uint8: + return uint16(value) + case uint16: + return value + } + } + floatValue := value.float64() + if math.IsNaN(floatValue) || math.IsInf(floatValue, 0) { + return 0 + } + if floatValue == 0 { + return 0 + } + remainder := math.Mod(floatValue, float_2_16) + if remainder > 0 { + remainder = math.Floor(remainder) + } else { + remainder = math.Ceil(remainder) + float_2_16 + } + return uint16(remainder) +} diff --git a/vendor/github.com/robertkrimen/otto/value_primitive.go b/vendor/github.com/robertkrimen/otto/value_primitive.go new file mode 100644 index 0000000..11ed329 --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/value_primitive.go @@ -0,0 +1,23 @@ +package otto + +func toStringPrimitive(value Value) Value { + return _toPrimitive(value, defaultValueHintString) +} + +func toNumberPrimitive(value Value) Value { + return _toPrimitive(value, defaultValueHintNumber) +} + +func toPrimitive(value Value) Value { + return _toPrimitive(value, defaultValueNoHint) +} + +func _toPrimitive(value Value, hint _defaultValueHint) Value { + switch value.kind { + case valueNull, valueUndefined, valueNumber, valueString, valueBoolean: + return value + case valueObject: + return value._object().DefaultValue(hint) + } + panic(hereBeDragons(value.kind, value)) +} diff --git a/vendor/github.com/robertkrimen/otto/value_string.go b/vendor/github.com/robertkrimen/otto/value_string.go new file mode 100644 index 0000000..0fbfd6b --- /dev/null +++ b/vendor/github.com/robertkrimen/otto/value_string.go @@ -0,0 +1,103 @@ +package otto + +import ( + "fmt" + "math" + "regexp" + "strconv" + "unicode/utf16" +) + +var matchLeading0Exponent = regexp.MustCompile(`([eE][\+\-])0+([1-9])`) // 1e-07 => 1e-7 + +// FIXME +// https://code.google.com/p/v8/source/browse/branches/bleeding_edge/src/conversions.cc?spec=svn18082&r=18082 +func floatToString(value float64, bitsize int) string { + // TODO Fit to ECMA-262 9.8.1 specification + if math.IsNaN(value) { + return "NaN" + } else if math.IsInf(value, 0) { + if math.Signbit(value) { + return "-Infinity" + } + return "Infinity" + } + exponent := math.Log10(math.Abs(value)) + if exponent >= 21 || exponent < -6 { + return matchLeading0Exponent.ReplaceAllString(strconv.FormatFloat(value, 'g', -1, bitsize), "$1$2") + } + return strconv.FormatFloat(value, 'f', -1, bitsize) +} + +func numberToStringRadix(value Value, radix int) string { + float := value.float64() + if math.IsNaN(float) { + return "NaN" + } else if math.IsInf(float, 1) { + return "Infinity" + } else if math.IsInf(float, -1) { + return "-Infinity" + } + // FIXME This is very broken + // Need to do proper radix conversion for floats, ... + // This truncates large floats (so bad). + return strconv.FormatInt(int64(float), radix) +} + +func (value Value) string() string { + if value.kind == valueString { + switch value := value.value.(type) { + case string: + return value + case []uint16: + return string(utf16.Decode(value)) + } + } + if value.IsUndefined() { + return "undefined" + } + if value.IsNull() { + return "null" + } + switch value := value.value.(type) { + case bool: + return strconv.FormatBool(value) + case int: + return strconv.FormatInt(int64(value), 10) + case int8: + return strconv.FormatInt(int64(value), 10) + case int16: + return strconv.FormatInt(int64(value), 10) + case int32: + return strconv.FormatInt(int64(value), 10) + case int64: + return strconv.FormatInt(value, 10) + case uint: + return strconv.FormatUint(uint64(value), 10) + case uint8: + return strconv.FormatUint(uint64(value), 10) + case uint16: + return strconv.FormatUint(uint64(value), 10) + case uint32: + return strconv.FormatUint(uint64(value), 10) + case uint64: + return strconv.FormatUint(value, 10) + case float32: + if value == 0 { + return "0" // Take care not to return -0 + } + return floatToString(float64(value), 32) + case float64: + if value == 0 { + return "0" // Take care not to return -0 + } + return floatToString(value, 64) + case []uint16: + return string(utf16.Decode(value)) + case string: + return value + case *_object: + return value.DefaultValue(defaultValueHintString).string() + } + panic(fmt.Errorf("%v.string( %T)", value.value, value.value)) +} diff --git a/vendor/github.com/scottferg/Go-SDL/gfx/constants.go b/vendor/github.com/scottferg/Go-SDL/gfx/constants.go new file mode 100644 index 0000000..db90ba1 --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/gfx/constants.go @@ -0,0 +1,7 @@ +package gfx + +const ( + FPS_UPPER_LIMIT = 200 + FPS_LOWER_LIMIT = 1 + FPS_DEFAULT = 30 +) diff --git a/vendor/github.com/scottferg/Go-SDL/gfx/framerate.go b/vendor/github.com/scottferg/Go-SDL/gfx/framerate.go new file mode 100644 index 0000000..bc3cd03 --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/gfx/framerate.go @@ -0,0 +1,57 @@ +/* +A pure Go version of SDL_framerate +*/ + +package gfx + +import ( + "time" +) + +type FPSmanager struct { + framecount uint32 + rateticks float64 + lastticks uint64 + rate uint32 +} + +func NewFramerate() *FPSmanager { + return &FPSmanager{ + framecount: 0, + rate: FPS_DEFAULT, + rateticks: (1000.0 / float64(FPS_DEFAULT)), + lastticks: uint64(time.Now().UnixNano()) / 1e6, + } +} + +func (manager *FPSmanager) SetFramerate(rate uint32) { + if rate >= FPS_LOWER_LIMIT && rate <= FPS_UPPER_LIMIT { + manager.framecount = 0 + manager.rate = rate + manager.rateticks = 1000.0 / float64(rate) + } else { + } +} + +func (manager *FPSmanager) GetFramerate() uint32 { + return manager.rate +} + +func (manager *FPSmanager) FramerateDelay() { + var current_ticks, target_ticks, the_delay uint64 + + // next frame + manager.framecount++ + + // get/calc ticks + current_ticks = uint64(time.Now().UnixNano()) / 1e6 + target_ticks = manager.lastticks + uint64(float64(manager.framecount)*manager.rateticks) + + if current_ticks <= target_ticks { + the_delay = target_ticks - current_ticks + time.Sleep(time.Duration(the_delay * 1e6)) + } else { + manager.framecount = 0 + manager.lastticks = uint64(time.Now().UnixNano()) / 1e6 + } +} diff --git a/vendor/github.com/scottferg/Go-SDL/sdl/audio/audio.go b/vendor/github.com/scottferg/Go-SDL/sdl/audio/audio.go new file mode 100644 index 0000000..8a096f5 --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/sdl/audio/audio.go @@ -0,0 +1,228 @@ +/* + * Copyright: ⚛ <0xe2.0x9a.0x9b@gmail.com> 2010 + * + * The contents of this file can be used freely, + * except for usages in immoral contexts. + */ + +/* +An interface to low-level SDL sound functions. +*/ +package audio + +// #cgo pkg-config: sdl +// #cgo freebsd LDFLAGS: -lrt +// #cgo linux LDFLAGS: -lrt +// #cgo windows LDFLAGS: -lpthread +// #include +// #include "callback.h" +import "C" +import "unsafe" +import "sync" + +// The version of Go-SDL audio bindings. +// The version descriptor changes into a new unique string +// after a semantically incompatible Go-SDL update. +// +// The returned value can be checked by users of this package +// to make sure they are using a version with the expected semantics. +// +// If Go adds some kind of support for package versioning, this function will go away. +func GoSdlAudioVersion() string { + return "⚛SDL audio bindings 1.0" +} + +// Audio format +const ( + AUDIO_U8 = C.AUDIO_U8 + AUDIO_S8 = C.AUDIO_S8 + AUDIO_U16LSB = C.AUDIO_U16LSB + AUDIO_S16LSB = C.AUDIO_S16LSB + AUDIO_U16MSB = C.AUDIO_U16MSB + AUDIO_S16MSB = C.AUDIO_S16MSB + AUDIO_U16 = C.AUDIO_U16 + AUDIO_S16 = C.AUDIO_S16 +) + +// Native audio byte ordering +const ( + AUDIO_U16SYS = C.AUDIO_U16SYS + AUDIO_S16SYS = C.AUDIO_S16SYS +) + +type AudioSpec struct { + Freq int + Format uint16 // If in doubt, use AUDIO_S16SYS + Channels uint8 // 1 or 2 + Out_Silence uint8 + Samples uint16 // A power of 2, preferrably 2^11 (2048) or more + Out_Size uint32 +} + +func OpenAudio(desired, obtained_orNil *AudioSpec) int { + var C_desired, C_obtained *C.SDL_AudioSpec + + C_desired = new(C.SDL_AudioSpec) + C_desired.freq = C.int(desired.Freq) + C_desired.format = C.Uint16(desired.Format) + C_desired.channels = C.Uint8(desired.Channels) + C_desired.samples = C.Uint16(desired.Samples) + C_desired.callback = C.callback_getCallback() + + if obtained_orNil != nil { + if desired != obtained_orNil { + C_obtained = new(C.SDL_AudioSpec) + } else { + C_obtained = C_desired + } + } + + status := C.SDL_OpenAudio(C_desired, C_obtained) + + if status == 0 { + mutex.Lock() + opened++ + mutex.Unlock() + } + + if obtained_orNil != nil { + obtained := obtained_orNil + + obtained.Freq = int(C_obtained.freq) + obtained.Format = uint16(C_obtained.format) + obtained.Channels = uint8(C_obtained.channels) + obtained.Samples = uint16(C_obtained.samples) + obtained.Out_Silence = uint8(C_obtained.silence) + obtained.Out_Size = uint32(C_obtained.size) + } + + return int(status) +} + +func CloseAudio() { + PauseAudio(true) + + mutex.Lock() + { + opened-- + switch { + case opened == 0: + userPaused = true + sdlPaused = true + case opened < 0: + panic("SDL audio not opened") + } + } + mutex.Unlock() + + C.callback_unblock() + + C.SDL_CloseAudio() +} + +// Audio status +const ( + SDL_AUDIO_STOPPED = C.SDL_AUDIO_STOPPED + SDL_AUDIO_PLAYING = C.SDL_AUDIO_PLAYING + SDL_AUDIO_PAUSED = C.SDL_AUDIO_PAUSED +) + +func GetAudioStatus() int { + return int(C.SDL_GetAudioStatus()) +} + +var opened int = 0 + +var userPaused bool = true +var sdlPaused bool = true +var haveData bool = false + +var mutex sync.Mutex + +// Pause or unpause the audio. +// Unpausing is deferred until a SendAudio function receives some samples. +func PauseAudio(pause_on bool) { + mutex.Lock() + + if pause_on != sdlPaused { + if pause_on { + // Pause SDL audio + userPaused = true + sdlPaused = true + C.SDL_PauseAudio(1) + } else { + userPaused = false + if haveData { + // Unpause SDL audio + sdlPaused = false + C.SDL_PauseAudio(0) + } else { + // Defer until SendAudio is called + } + } + } + + mutex.Unlock() +} + +func LockAudio() { + C.SDL_LockAudio() +} + +func UnlockAudio() { + C.SDL_UnlockAudio() +} + +// Send samples to the audio device (AUDIO_S16SYS format). +// This function blocks until all the samples are consumed by the SDL audio thread. +func SendAudio_int16(data []int16) { + if len(data) > 0 { + sendAudio((*C.Uint8)(unsafe.Pointer(&data[0])), C.size_t(int(unsafe.Sizeof(data[0]))*len(data))) + } +} + +// Send samples to the audio device (AUDIO_U16SYS format). +// This function blocks until all the samples are consumed by the SDL audio thread. +func SendAudio_uint16(data []uint16) { + if len(data) > 0 { + sendAudio((*C.Uint8)(unsafe.Pointer(&data[0])), C.size_t(int(unsafe.Sizeof(data[0]))*len(data))) + } +} + +// Send samples to the audio device (AUDIO_S8 format). +// This function blocks until all the samples are consumed by the SDL audio thread. +func SendAudio_int8(data []int8) { + if len(data) > 0 { + sendAudio((*C.Uint8)(unsafe.Pointer(&data[0])), C.size_t(int(unsafe.Sizeof(data[0]))*len(data))) + } +} + +// Send samples to the audio device (AUDIO_U8 format). +// This function blocks until all the samples are consumed by the SDL audio thread. +func SendAudio_uint8(data []uint8) { + if len(data) > 0 { + sendAudio((*C.Uint8)(unsafe.Pointer(&data[0])), C.size_t(int(unsafe.Sizeof(data[0]))*len(data))) + } +} + +func sendAudio(data *C.Uint8, numBytes C.size_t) { + if numBytes > 0 { + mutex.Lock() + { + haveData = true + + if (userPaused == false) && (sdlPaused == true) { + // Unpause SDL audio + sdlPaused = false + C.SDL_PauseAudio(0) + } + } + mutex.Unlock() + + C.callback_fillBuffer(data, numBytes) + + mutex.Lock() + haveData = false + mutex.Unlock() + } +} diff --git a/vendor/github.com/scottferg/Go-SDL/sdl/audio/callback.c b/vendor/github.com/scottferg/Go-SDL/sdl/audio/callback.c new file mode 100644 index 0000000..1ac0531 --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/sdl/audio/callback.c @@ -0,0 +1,179 @@ +/* + * Copyright: ⚛ <0xe2.0x9a.0x9b@gmail.com> 2010 + * + * The contents of this file can be used freely, + * except for usages in immoral contexts. + */ + +#include "callback.h" +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +// Uncomment the next line to enable debugging messages +//#define DEBUG + +static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t need = PTHREAD_COND_INITIALIZER; +static pthread_cond_t avail = PTHREAD_COND_INITIALIZER; +static size_t needed = 0; // Number of bytes needed by the consumer +static size_t available = 0; // Number of bytes available (from the producer) + +static Uint8 *stream; // Communication buffer between the consumer and the producer + +#ifdef DEBUG +#include +static int64_t get_time() { + struct timespec ts; + if(clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + return 1000000000*(int64_t)ts.tv_sec + (int64_t)ts.tv_nsec; + else + return -1; +} +#endif + +#ifdef DEBUG +static uint64_t cummulativeLatency = 0; +static unsigned numCallbacks = 0; +#endif + +static void SDLCALL callback(void *userdata, Uint8 *_stream, int _len) { + assert(_len > 0); + + size_t len = (size_t)_len; + + pthread_mutex_lock(&m); + { + assert(available == 0); + stream = _stream; + + { + #ifdef DEBUG + int64_t t1 = get_time(); + printf("consumer: t1=%lld µs\n", (long long)t1/1000); + #endif + + assert(needed == 0); + #ifdef DEBUG + printf("consumer: needed <- %zu\n", len); + #endif + needed = len; + pthread_cond_signal(&need); + + #ifdef DEBUG + printf("consumer: waiting for data\n"); + #endif + pthread_cond_wait(&avail, &m); + assert(needed == 0); + assert(available == len); + + #ifdef DEBUG + int64_t t2 = get_time(); + printf("consumer: t2=%lld µs\n", (long long)t2/1000); + if(t1>0 && t2>0) { + uint64_t latency = t2-t1; + cummulativeLatency += latency; + numCallbacks++; + printf("consumer: latency=%lld µs, avg=%u µs\n", + (long long)(latency/1000), + (unsigned)(cummulativeLatency/numCallbacks/1000)); + } + #endif + } + + #ifdef DEBUG + printf("consumer: received %zu bytes of data\n", available); + printf("consumer: available <- 0\n"); + #endif + available = 0; + stream = NULL; + } + pthread_mutex_unlock(&m); +} + +callback_t callback_getCallback() { + return &callback; +} + +void callback_fillBuffer(Uint8 *data, size_t numBytes) { + size_t sent = 0; + + pthread_mutex_lock(&m); + + while(sent < numBytes) { + #ifdef DEBUG + int64_t t = get_time(); + printf("producer: t=%lld µs\n", (long long)t/1000); + #endif + + if(needed == 0) { + #ifdef DEBUG + printf("producer: waiting until data is needed (1)\n"); + #endif + pthread_cond_wait(&need, &m); + + // Interrupted from 'callback_unblock' ? + if(needed == 0) { + #ifdef DEBUG + printf("producer: interrupted (1)\n"); + #endif + break; + } + } + + assert(stream != NULL); + assert(needed > 0); + + // Append a chunk of data to the 'stream' + size_t n = (needed<(numBytes-sent)) ? needed : (numBytes-sent); + memcpy(stream+available, data+sent, n); + available += n; + sent += n; + needed -= n; + + #ifdef DEBUG + printf("producer: added %zu bytes, available=%zu\n", n, available); + #endif + + if(needed == 0) { + pthread_cond_signal(&avail); + if(sent < numBytes) { + #ifdef DEBUG + printf("producer: waiting until data is needed (2)\n"); + #endif + pthread_cond_wait(&need, &m); + + // Interrupted from 'callback_unblock' ? + if(needed == 0) { + #ifdef DEBUG + printf("producer: interrupted (2)\n"); + #endif + break; + } + } + else { + break; + } + } + } + + pthread_mutex_unlock(&m); +} + +void callback_unblock() { + pthread_mutex_lock(&m); + if(needed > 0) { + // Note: SDL already prefilled the entire 'stream' with silence + assert(stream != NULL); + available += needed; + needed = 0; + pthread_cond_signal(&avail); + } + pthread_cond_signal(&need); + pthread_mutex_unlock(&m); +} + diff --git a/vendor/github.com/scottferg/Go-SDL/sdl/audio/callback.h b/vendor/github.com/scottferg/Go-SDL/sdl/audio/callback.h new file mode 100644 index 0000000..8e181ae --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/sdl/audio/callback.h @@ -0,0 +1,15 @@ +/* + * Copyright: ⚛ <0xe2.0x9a.0x9b@gmail.com> 2010 + * + * The contents of this file can be used freely, + * except for usages in immoral contexts. + */ + +#include + +typedef void (SDLCALL *callback_t)(void *userdata, Uint8 *stream, int len); + +extern callback_t callback_getCallback(); +extern void callback_fillBuffer(Uint8 *data, size_t numBytes); +extern void callback_unblock(); + diff --git a/vendor/github.com/scottferg/Go-SDL/sdl/constants.go b/vendor/github.com/scottferg/Go-SDL/sdl/constants.go new file mode 100644 index 0000000..c1031b8 --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/sdl/constants.go @@ -0,0 +1,417 @@ +package sdl + +// #cgo pkg-config: sdl +// #include +import "C" + +const ( + // init flags + + INIT_AUDIO = C.SDL_INIT_AUDIO + INIT_VIDEO = C.SDL_INIT_VIDEO + INIT_CDROM = C.SDL_INIT_CDROM + INIT_TIMER = C.SDL_INIT_TIMER + INIT_JOYSTICK = C.SDL_INIT_JOYSTICK + INIT_NOPARACHUTE = C.SDL_INIT_NOPARACHUTE + INIT_EVENTTHREAD = C.SDL_INIT_EVENTTHREAD + INIT_EVERYTHING = C.SDL_INIT_EVERYTHING + + // application states + + APPMOUSEFOCUS = C.SDL_APPMOUSEFOCUS + APPINPUTFOCUS = C.SDL_APPINPUTFOCUS + APPACTIVE = C.SDL_APPACTIVE + + // setvideo flags + + SWSURFACE = C.SDL_SWSURFACE + HWSURFACE = C.SDL_HWSURFACE + ASYNCBLIT = C.SDL_ASYNCBLIT + ANYFORMAT = C.SDL_ANYFORMAT + HWPALETTE = C.SDL_HWPALETTE + DOUBLEBUF = C.SDL_DOUBLEBUF + FULLSCREEN = C.SDL_FULLSCREEN + OPENGL = C.SDL_OPENGL + OPENGLBLIT = C.SDL_OPENGLBLIT + RESIZABLE = C.SDL_RESIZABLE + NOFRAME = C.SDL_NOFRAME + HWACCEL = C.SDL_HWACCEL + SRCCOLORKEY = C.SDL_SRCCOLORKEY + RLEACCELOK = C.SDL_RLEACCELOK + RLEACCEL = C.SDL_RLEACCEL + SRCALPHA = C.SDL_SRCALPHA + PREALLOC = C.SDL_PREALLOC + YV12_OVERLAY = C.SDL_YV12_OVERLAY + IYUV_OVERLAY = C.SDL_IYUV_OVERLAY + YUY2_OVERLAY = C.SDL_YUY2_OVERLAY + UYVY_OVERLAY = C.SDL_UYVY_OVERLAY + YVYU_OVERLAY = C.SDL_YVYU_OVERLAY + LOGPAL = C.SDL_LOGPAL + PHYSPAL = C.SDL_PHYSPAL + + // More setvideo flags: GLattr enumeration + + GL_RED_SIZE = C.SDL_GL_RED_SIZE + GL_GREEN_SIZE = C.SDL_GL_GREEN_SIZE + GL_BLUE_SIZE = C.SDL_GL_BLUE_SIZE + GL_ALPHA_SIZE = C.SDL_GL_ALPHA_SIZE + GL_BUFFER_SIZE = C.SDL_GL_BUFFER_SIZE + GL_DOUBLEBUFFER = C.SDL_GL_DOUBLEBUFFER + GL_DEPTH_SIZE = C.SDL_GL_DEPTH_SIZE + GL_STENCIL_SIZE = C.SDL_GL_STENCIL_SIZE + GL_ACCUM_RED_SIZE = C.SDL_GL_ACCUM_RED_SIZE + GL_ACCUM_GREEN_SIZE = C.SDL_GL_ACCUM_GREEN_SIZE + GL_ACCUM_BLUE_SIZE = C.SDL_GL_ACCUM_BLUE_SIZE + GL_ACCUM_ALPHA_SIZE = C.SDL_GL_ACCUM_ALPHA_SIZE + GL_STEREO = C.SDL_GL_STEREO + GL_MULTISAMPLEBUFFERS = C.SDL_GL_MULTISAMPLEBUFFERS + GL_MULTISAMPLESAMPLES = C.SDL_GL_MULTISAMPLESAMPLES + GL_ACCELERATED_VISUAL = C.SDL_GL_ACCELERATED_VISUAL + GL_SWAP_CONTROL = C.SDL_GL_SWAP_CONTROL + + // event types + + NOEVENT = C.SDL_NOEVENT + ACTIVEEVENT = C.SDL_ACTIVEEVENT + KEYDOWN = C.SDL_KEYDOWN + KEYUP = C.SDL_KEYUP + MOUSEMOTION = C.SDL_MOUSEMOTION + MOUSEBUTTONDOWN = C.SDL_MOUSEBUTTONDOWN + MOUSEBUTTONUP = C.SDL_MOUSEBUTTONUP + JOYAXISMOTION = C.SDL_JOYAXISMOTION + JOYBALLMOTION = C.SDL_JOYBALLMOTION + JOYHATMOTION = C.SDL_JOYHATMOTION + JOYBUTTONDOWN = C.SDL_JOYBUTTONDOWN + JOYBUTTONUP = C.SDL_JOYBUTTONUP + QUIT = C.SDL_QUIT + SYSWMEVENT = C.SDL_SYSWMEVENT + EVENT_RESERVEDA = C.SDL_EVENT_RESERVEDA + EVENT_RESERVEDB = C.SDL_EVENT_RESERVEDB + VIDEORESIZE = C.SDL_VIDEORESIZE + VIDEOEXPOSE = C.SDL_VIDEOEXPOSE + EVENT_RESERVED2 = C.SDL_EVENT_RESERVED2 + EVENT_RESERVED3 = C.SDL_EVENT_RESERVED3 + EVENT_RESERVED4 = C.SDL_EVENT_RESERVED4 + EVENT_RESERVED5 = C.SDL_EVENT_RESERVED5 + EVENT_RESERVED6 = C.SDL_EVENT_RESERVED6 + EVENT_RESERVED7 = C.SDL_EVENT_RESERVED7 + + USEREVENT = C.SDL_USEREVENT + + NUMEVENTS = C.SDL_NUMEVENTS + + // event masks + + ACTIVEEVENTMASK = C.SDL_ACTIVEEVENTMASK + KEYDOWNMASK = C.SDL_KEYDOWNMASK + KEYUPMASK = C.SDL_KEYUPMASK + KEYEVENTMASK = C.SDL_KEYEVENTMASK + MOUSEMOTIONMASK = C.SDL_MOUSEMOTIONMASK + MOUSEBUTTONDOWNMASK = C.SDL_MOUSEBUTTONDOWNMASK + MOUSEBUTTONUPMASK = C.SDL_MOUSEBUTTONUPMASK + MOUSEEVENTMASK = C.SDL_MOUSEEVENTMASK + JOYAXISMOTIONMASK = C.SDL_JOYAXISMOTIONMASK + JOYBALLMOTIONMASK = C.SDL_JOYBALLMOTIONMASK + JOYHATMOTIONMASK = C.SDL_JOYHATMOTIONMASK + JOYBUTTONDOWNMASK = C.SDL_JOYBUTTONDOWNMASK + JOYBUTTONUPMASK = C.SDL_JOYBUTTONUPMASK + JOYEVENTMASK = C.SDL_JOYEVENTMASK + VIDEORESIZEMASK = C.SDL_VIDEORESIZEMASK + VIDEOEXPOSEMASK = C.SDL_VIDEOEXPOSEMASK + QUITMASK = C.SDL_QUITMASK + SYSWMEVENTMASK = C.SDL_SYSWMEVENTMASK + + // event state + + QUERY = C.SDL_QUERY + DISABLE = C.SDL_DISABLE + ENABLE = C.SDL_ENABLE + + // keys + K_UNKNOWN = C.SDLK_UNKNOWN + K_FIRST = C.SDLK_FIRST + K_BACKSPACE = C.SDLK_BACKSPACE + K_TAB = C.SDLK_TAB + K_CLEAR = C.SDLK_CLEAR + K_RETURN = C.SDLK_RETURN + K_PAUSE = C.SDLK_PAUSE + K_ESCAPE = C.SDLK_ESCAPE + K_SPACE = C.SDLK_SPACE + K_EXCLAIM = C.SDLK_EXCLAIM + K_QUOTEDBL = C.SDLK_QUOTEDBL + K_HASH = C.SDLK_HASH + K_DOLLAR = C.SDLK_DOLLAR + K_AMPERSAND = C.SDLK_AMPERSAND + K_QUOTE = C.SDLK_QUOTE + K_LEFTPAREN = C.SDLK_LEFTPAREN + K_RIGHTPAREN = C.SDLK_RIGHTPAREN + K_ASTERISK = C.SDLK_ASTERISK + K_PLUS = C.SDLK_PLUS + K_COMMA = C.SDLK_COMMA + K_MINUS = C.SDLK_MINUS + K_PERIOD = C.SDLK_PERIOD + K_SLASH = C.SDLK_SLASH + K_0 = C.SDLK_0 + K_1 = C.SDLK_1 + K_2 = C.SDLK_2 + K_3 = C.SDLK_3 + K_4 = C.SDLK_4 + K_5 = C.SDLK_5 + K_6 = C.SDLK_6 + K_7 = C.SDLK_7 + K_8 = C.SDLK_8 + K_9 = C.SDLK_9 + K_COLON = C.SDLK_COLON + K_SEMICOLON = C.SDLK_SEMICOLON + K_LESS = C.SDLK_LESS + K_EQUALS = C.SDLK_EQUALS + K_GREATER = C.SDLK_GREATER + K_QUESTION = C.SDLK_QUESTION + K_AT = C.SDLK_AT + K_LEFTBRACKET = C.SDLK_LEFTBRACKET + K_BACKSLASH = C.SDLK_BACKSLASH + K_RIGHTBRACKET = C.SDLK_RIGHTBRACKET + K_CARET = C.SDLK_CARET + K_UNDERSCORE = C.SDLK_UNDERSCORE + K_BACKQUOTE = C.SDLK_BACKQUOTE + K_a = C.SDLK_a + K_b = C.SDLK_b + K_c = C.SDLK_c + K_d = C.SDLK_d + K_e = C.SDLK_e + K_f = C.SDLK_f + K_g = C.SDLK_g + K_h = C.SDLK_h + K_i = C.SDLK_i + K_j = C.SDLK_j + K_k = C.SDLK_k + K_l = C.SDLK_l + K_m = C.SDLK_m + K_n = C.SDLK_n + K_o = C.SDLK_o + K_p = C.SDLK_p + K_q = C.SDLK_q + K_r = C.SDLK_r + K_s = C.SDLK_s + K_t = C.SDLK_t + K_u = C.SDLK_u + K_v = C.SDLK_v + K_w = C.SDLK_w + K_x = C.SDLK_x + K_y = C.SDLK_y + K_z = C.SDLK_z + K_DELETE = C.SDLK_DELETE + K_WORLD_0 = C.SDLK_WORLD_0 + K_WORLD_1 = C.SDLK_WORLD_1 + K_WORLD_2 = C.SDLK_WORLD_2 + K_WORLD_3 = C.SDLK_WORLD_3 + K_WORLD_4 = C.SDLK_WORLD_4 + K_WORLD_5 = C.SDLK_WORLD_5 + K_WORLD_6 = C.SDLK_WORLD_6 + K_WORLD_7 = C.SDLK_WORLD_7 + K_WORLD_8 = C.SDLK_WORLD_8 + K_WORLD_9 = C.SDLK_WORLD_9 + K_WORLD_10 = C.SDLK_WORLD_10 + K_WORLD_11 = C.SDLK_WORLD_11 + K_WORLD_12 = C.SDLK_WORLD_12 + K_WORLD_13 = C.SDLK_WORLD_13 + K_WORLD_14 = C.SDLK_WORLD_14 + K_WORLD_15 = C.SDLK_WORLD_15 + K_WORLD_16 = C.SDLK_WORLD_16 + K_WORLD_17 = C.SDLK_WORLD_17 + K_WORLD_18 = C.SDLK_WORLD_18 + K_WORLD_19 = C.SDLK_WORLD_19 + K_WORLD_20 = C.SDLK_WORLD_20 + K_WORLD_21 = C.SDLK_WORLD_21 + K_WORLD_22 = C.SDLK_WORLD_22 + K_WORLD_23 = C.SDLK_WORLD_23 + K_WORLD_24 = C.SDLK_WORLD_24 + K_WORLD_25 = C.SDLK_WORLD_25 + K_WORLD_26 = C.SDLK_WORLD_26 + K_WORLD_27 = C.SDLK_WORLD_27 + K_WORLD_28 = C.SDLK_WORLD_28 + K_WORLD_29 = C.SDLK_WORLD_29 + K_WORLD_30 = C.SDLK_WORLD_30 + K_WORLD_31 = C.SDLK_WORLD_31 + K_WORLD_32 = C.SDLK_WORLD_32 + K_WORLD_33 = C.SDLK_WORLD_33 + K_WORLD_34 = C.SDLK_WORLD_34 + K_WORLD_35 = C.SDLK_WORLD_35 + K_WORLD_36 = C.SDLK_WORLD_36 + K_WORLD_37 = C.SDLK_WORLD_37 + K_WORLD_38 = C.SDLK_WORLD_38 + K_WORLD_39 = C.SDLK_WORLD_39 + K_WORLD_40 = C.SDLK_WORLD_40 + K_WORLD_41 = C.SDLK_WORLD_41 + K_WORLD_42 = C.SDLK_WORLD_42 + K_WORLD_43 = C.SDLK_WORLD_43 + K_WORLD_44 = C.SDLK_WORLD_44 + K_WORLD_45 = C.SDLK_WORLD_45 + K_WORLD_46 = C.SDLK_WORLD_46 + K_WORLD_47 = C.SDLK_WORLD_47 + K_WORLD_48 = C.SDLK_WORLD_48 + K_WORLD_49 = C.SDLK_WORLD_49 + K_WORLD_50 = C.SDLK_WORLD_50 + K_WORLD_51 = C.SDLK_WORLD_51 + K_WORLD_52 = C.SDLK_WORLD_52 + K_WORLD_53 = C.SDLK_WORLD_53 + K_WORLD_54 = C.SDLK_WORLD_54 + K_WORLD_55 = C.SDLK_WORLD_55 + K_WORLD_56 = C.SDLK_WORLD_56 + K_WORLD_57 = C.SDLK_WORLD_57 + K_WORLD_58 = C.SDLK_WORLD_58 + K_WORLD_59 = C.SDLK_WORLD_59 + K_WORLD_60 = C.SDLK_WORLD_60 + K_WORLD_61 = C.SDLK_WORLD_61 + K_WORLD_62 = C.SDLK_WORLD_62 + K_WORLD_63 = C.SDLK_WORLD_63 + K_WORLD_64 = C.SDLK_WORLD_64 + K_WORLD_65 = C.SDLK_WORLD_65 + K_WORLD_66 = C.SDLK_WORLD_66 + K_WORLD_67 = C.SDLK_WORLD_67 + K_WORLD_68 = C.SDLK_WORLD_68 + K_WORLD_69 = C.SDLK_WORLD_69 + K_WORLD_70 = C.SDLK_WORLD_70 + K_WORLD_71 = C.SDLK_WORLD_71 + K_WORLD_72 = C.SDLK_WORLD_72 + K_WORLD_73 = C.SDLK_WORLD_73 + K_WORLD_74 = C.SDLK_WORLD_74 + K_WORLD_75 = C.SDLK_WORLD_75 + K_WORLD_76 = C.SDLK_WORLD_76 + K_WORLD_77 = C.SDLK_WORLD_77 + K_WORLD_78 = C.SDLK_WORLD_78 + K_WORLD_79 = C.SDLK_WORLD_79 + K_WORLD_80 = C.SDLK_WORLD_80 + K_WORLD_81 = C.SDLK_WORLD_81 + K_WORLD_82 = C.SDLK_WORLD_82 + K_WORLD_83 = C.SDLK_WORLD_83 + K_WORLD_84 = C.SDLK_WORLD_84 + K_WORLD_85 = C.SDLK_WORLD_85 + K_WORLD_86 = C.SDLK_WORLD_86 + K_WORLD_87 = C.SDLK_WORLD_87 + K_WORLD_88 = C.SDLK_WORLD_88 + K_WORLD_89 = C.SDLK_WORLD_89 + K_WORLD_90 = C.SDLK_WORLD_90 + K_WORLD_91 = C.SDLK_WORLD_91 + K_WORLD_92 = C.SDLK_WORLD_92 + K_WORLD_93 = C.SDLK_WORLD_93 + K_WORLD_94 = C.SDLK_WORLD_94 + K_WORLD_95 = C.SDLK_WORLD_95 + K_KP0 = C.SDLK_KP0 + K_KP1 = C.SDLK_KP1 + K_KP2 = C.SDLK_KP2 + K_KP3 = C.SDLK_KP3 + K_KP4 = C.SDLK_KP4 + K_KP5 = C.SDLK_KP5 + K_KP6 = C.SDLK_KP6 + K_KP7 = C.SDLK_KP7 + K_KP8 = C.SDLK_KP8 + K_KP9 = C.SDLK_KP9 + K_KP_PERIOD = C.SDLK_KP_PERIOD + K_KP_DIVIDE = C.SDLK_KP_DIVIDE + K_KP_MULTIPLY = C.SDLK_KP_MULTIPLY + K_KP_MINUS = C.SDLK_KP_MINUS + K_KP_PLUS = C.SDLK_KP_PLUS + K_KP_ENTER = C.SDLK_KP_ENTER + K_KP_EQUALS = C.SDLK_KP_EQUALS + K_UP = C.SDLK_UP + K_DOWN = C.SDLK_DOWN + K_RIGHT = C.SDLK_RIGHT + K_LEFT = C.SDLK_LEFT + K_INSERT = C.SDLK_INSERT + K_HOME = C.SDLK_HOME + K_END = C.SDLK_END + K_PAGEUP = C.SDLK_PAGEUP + K_PAGEDOWN = C.SDLK_PAGEDOWN + K_F1 = C.SDLK_F1 + K_F2 = C.SDLK_F2 + K_F3 = C.SDLK_F3 + K_F4 = C.SDLK_F4 + K_F5 = C.SDLK_F5 + K_F6 = C.SDLK_F6 + K_F7 = C.SDLK_F7 + K_F8 = C.SDLK_F8 + K_F9 = C.SDLK_F9 + K_F10 = C.SDLK_F10 + K_F11 = C.SDLK_F11 + K_F12 = C.SDLK_F12 + K_F13 = C.SDLK_F13 + K_F14 = C.SDLK_F14 + K_F15 = C.SDLK_F15 + K_NUMLOCK = C.SDLK_NUMLOCK + K_CAPSLOCK = C.SDLK_CAPSLOCK + K_SCROLLOCK = C.SDLK_SCROLLOCK + K_RSHIFT = C.SDLK_RSHIFT + K_LSHIFT = C.SDLK_LSHIFT + K_RCTRL = C.SDLK_RCTRL + K_LCTRL = C.SDLK_LCTRL + K_RALT = C.SDLK_RALT + K_LALT = C.SDLK_LALT + K_RMETA = C.SDLK_RMETA + K_LMETA = C.SDLK_LMETA + K_LSUPER = C.SDLK_LSUPER + K_RSUPER = C.SDLK_RSUPER + K_MODE = C.SDLK_MODE + K_COMPOSE = C.SDLK_COMPOSE + K_HELP = C.SDLK_HELP + K_PRINT = C.SDLK_PRINT + K_SYSREQ = C.SDLK_SYSREQ + K_BREAK = C.SDLK_BREAK + K_MENU = C.SDLK_MENU + K_POWER = C.SDLK_POWER + K_EURO = C.SDLK_EURO + K_UNDO = C.SDLK_UNDO + + // key mods + + KMOD_NONE = C.KMOD_NONE + KMOD_LSHIFT = C.KMOD_LSHIFT + KMOD_RSHIFT = C.KMOD_RSHIFT + KMOD_LCTRL = C.KMOD_LCTRL + KMOD_RCTRL = C.KMOD_RCTRL + KMOD_LALT = C.KMOD_LALT + KMOD_RALT = C.KMOD_RALT + KMOD_LMETA = C.KMOD_LMETA + KMOD_RMETA = C.KMOD_RMETA + KMOD_NUM = C.KMOD_NUM + KMOD_CAPS = C.KMOD_CAPS + KMOD_MODE = C.KMOD_MODE + KMOD_RESERVED = C.KMOD_RESERVED + + // hat states + + HAT_CENTERED = C.SDL_HAT_CENTERED + HAT_UP = C.SDL_HAT_UP + HAT_RIGHT = C.SDL_HAT_RIGHT + HAT_DOWN = C.SDL_HAT_DOWN + HAT_LEFT = C.SDL_HAT_LEFT + HAT_RIGHTUP = C.SDL_HAT_RIGHTUP + HAT_RIGHTDOWN = C.SDL_HAT_RIGHTDOWN + HAT_LEFTUP = C.SDL_HAT_LEFTUP + HAT_LEFTDOWN = C.SDL_HAT_LEFTDOWN + + // keyboard/mouse state + + RELEASED = C.SDL_RELEASED + PRESSED = C.SDL_PRESSED + + // mouse button constants + + BUTTON_LEFT = C.SDL_BUTTON_LEFT + BUTTON_MIDDLE = C.SDL_BUTTON_MIDDLE + BUTTON_RIGHT = C.SDL_BUTTON_RIGHT + BUTTON_WHEELUP = C.SDL_BUTTON_WHEELUP + BUTTON_WHEELDOWN = C.SDL_BUTTON_WHEELDOWN + BUTTON_X1 = C.SDL_BUTTON_X1 + BUTTON_X2 = C.SDL_BUTTON_X2 + + // mouse button masks + + BUTTON_LMASK = 1 << (BUTTON_LEFT - 1) + BUTTON_MMASK = 1 << (BUTTON_MIDDLE - 1) + BUTTON_RMASK = 1 << (BUTTON_RIGHT - 1) + BUTTON_WHEELUPMASK = 1 << (BUTTON_WHEELUP - 1) + BUTTON_WHEELDOWNMASK = 1 << (BUTTON_WHEELDOWN - 1) + BUTTON_X1MASK = 1 << (BUTTON_X1 - 1) + BUTTON_X2MASK = 1 << (BUTTON_X2 - 1) +) diff --git a/vendor/github.com/scottferg/Go-SDL/sdl/event.go b/vendor/github.com/scottferg/Go-SDL/sdl/event.go new file mode 100644 index 0000000..a21e2ca --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/sdl/event.go @@ -0,0 +1,65 @@ +package sdl + +import "time" + +var events chan interface{} = make(chan interface{}) + +// This channel delivers SDL events. Each object received from this channel +// has one of the following types: sdl.QuitEvent, sdl.KeyboardEvent, +// sdl.MouseButtonEvent, sdl.MouseMotionEvent, sdl.ActiveEvent, +// sdl.ResizeEvent, sdl.JoyAxisEvent, sdl.JoyButtonEvent, sdl.JoyHatEvent, +// sdl.JoyBallEvent +var Events <-chan interface{} = events + +// Polling interval, in milliseconds +const poll_interval_ms = 10 + +// Polls SDL events in periodic intervals. +// This function does not return. +func pollEvents() { + // It is more efficient to create the event-object here once, + // rather than multiple times within the loop + event := &Event{} + + for { + for event.poll() { + switch event.Type { + case QUIT: + events <- *(*QuitEvent)(cast(event)) + + case KEYDOWN, KEYUP: + events <- *(*KeyboardEvent)(cast(event)) + + case MOUSEBUTTONDOWN, MOUSEBUTTONUP: + events <- *(*MouseButtonEvent)(cast(event)) + + case MOUSEMOTION: + events <- *(*MouseMotionEvent)(cast(event)) + + case JOYAXISMOTION: + events <- *(*JoyAxisEvent)(cast(event)) + + case JOYBUTTONDOWN, JOYBUTTONUP: + events <- *(*JoyButtonEvent)(cast(event)) + + case JOYHATMOTION: + events <- *(*JoyHatEvent)(cast(event)) + + case JOYBALLMOTION: + events <- *(*JoyBallEvent)(cast(event)) + + case ACTIVEEVENT: + events <- *(*ActiveEvent)(cast(event)) + + case VIDEORESIZE: + events <- *(*ResizeEvent)(cast(event)) + } + } + + time.Sleep(poll_interval_ms * 1e6) + } +} + +func init() { + go pollEvents() +} diff --git a/vendor/github.com/scottferg/Go-SDL/sdl/sdl.go b/vendor/github.com/scottferg/Go-SDL/sdl/sdl.go new file mode 100644 index 0000000..fbce8e9 --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/sdl/sdl.go @@ -0,0 +1,874 @@ +/* +A binding of SDL and SDL_image. + +The binding works in pretty much the same way as it does in C, although +some of the functions have been altered to give them an object-oriented +flavor (eg. Rather than sdl.Flip(surface) it's surface.Flip() ) +*/ +package sdl + +// #cgo pkg-config: sdl SDL_image +// +// struct private_hwdata{}; +// struct SDL_BlitMap{}; +// #define map _map +// +// #include +// #include +import "C" + +import ( + "os" + "reflect" + "runtime" + "sync" + "time" + "unsafe" +) + +type cast unsafe.Pointer + +// Mutex for serialization of access to certain SDL functions. +// +// There is no need to use this in application code, the mutex is a public variable +// just because it needs to be accessible from other parts of Go-SDL (such as package "sdl/ttf"). +// +// Surface-level functions (such as 'Surface.Blit') are not using this mutex, +// so it is possible to modify multiple surfaces concurrently. +// There is no dependency between 'Surface.Lock' and the global mutex. +var GlobalMutex sync.Mutex + +type Surface struct { + cSurface *C.SDL_Surface + mutex sync.RWMutex + + Flags uint32 + Format *PixelFormat + W int32 + H int32 + Pitch uint16 + Pixels unsafe.Pointer + Offset int32 + + gcPixels interface{} // Prevents garbage collection of pixels passed to func CreateRGBSurfaceFrom +} + +func wrap(cSurface *C.SDL_Surface) *Surface { + var s *Surface + + if cSurface != nil { + var surface Surface + surface.SetCSurface(unsafe.Pointer(cSurface)) + s = &surface + } else { + s = nil + } + + return s +} + +// FIXME: Ideally, this should NOT be a public function, but it is needed in the package "ttf" ... +func (s *Surface) SetCSurface(cSurface unsafe.Pointer) { + s.cSurface = (*C.SDL_Surface)(cSurface) + s.reload() +} + +// Pull data from C.SDL_Surface. +// Make sure to use this when the C surface might have been changed. +func (s *Surface) reload() { + s.Flags = uint32(s.cSurface.flags) + s.Format = (*PixelFormat)(cast(s.cSurface.format)) + s.W = int32(s.cSurface.w) + s.H = int32(s.cSurface.h) + s.Pitch = uint16(s.cSurface.pitch) + s.Pixels = s.cSurface.pixels + s.Offset = int32(s.cSurface.offset) +} + +func (s *Surface) destroy() { + s.cSurface = nil + s.Format = nil + s.Pixels = nil + s.gcPixels = nil +} + +// ======= +// General +// ======= + +// The version of Go-SDL bindings. +// The version descriptor changes into a new unique string +// after a semantically incompatible Go-SDL update. +// +// The returned value can be checked by users of this package +// to make sure they are using a version with the expected semantics. +// +// If Go adds some kind of support for package versioning, this function will go away. +func GoSdlVersion() string { + return "⚛SDL bindings 1.0" +} + +// Initializes SDL. +func Init(flags uint32) int { + GlobalMutex.Lock() + status := int(C.SDL_Init(C.Uint32(flags))) + if (status != 0) && (runtime.GOOS == "darwin") && (flags&INIT_VIDEO != 0) { + if os.Getenv("SDL_VIDEODRIVER") == "" { + os.Setenv("SDL_VIDEODRIVER", "x11") + status = int(C.SDL_Init(C.Uint32(flags))) + if status != 0 { + os.Setenv("SDL_VIDEODRIVER", "") + } + } + } + + GlobalMutex.Unlock() + return status +} + +// Shuts down SDL +func Quit() { + GlobalMutex.Lock() + + if currentVideoSurface != nil { + currentVideoSurface.destroy() + currentVideoSurface = nil + } + + C.SDL_Quit() + + GlobalMutex.Unlock() +} + +// Initializes subsystems. +func InitSubSystem(flags uint32) int { + GlobalMutex.Lock() + status := int(C.SDL_InitSubSystem(C.Uint32(flags))) + if (status != 0) && (runtime.GOOS == "darwin") && (flags&INIT_VIDEO != 0) { + if os.Getenv("SDL_VIDEODRIVER") == "" { + os.Setenv("SDL_VIDEODRIVER", "x11") + status = int(C.SDL_InitSubSystem(C.Uint32(flags))) + if status != 0 { + os.Setenv("SDL_VIDEODRIVER", "") + } + } + } + GlobalMutex.Unlock() + return status +} + +// Shuts down a subsystem. +func QuitSubSystem(flags uint32) { + GlobalMutex.Lock() + C.SDL_QuitSubSystem(C.Uint32(flags)) + GlobalMutex.Unlock() +} + +// Checks which subsystems are initialized. +func WasInit(flags uint32) int { + GlobalMutex.Lock() + status := int(C.SDL_WasInit(C.Uint32(flags))) + GlobalMutex.Unlock() + return status +} + +// ============== +// Error Handling +// ============== + +// Gets SDL error string +func GetError() string { + GlobalMutex.Lock() + s := C.GoString(C.SDL_GetError()) + GlobalMutex.Unlock() + return s +} + +// Clear the current SDL error +func ClearError() { + GlobalMutex.Lock() + C.SDL_ClearError() + GlobalMutex.Unlock() +} + +// ====== +// Video +// ====== + +var currentVideoSurface *Surface = nil + +// Sets up a video mode with the specified width, height, bits-per-pixel and +// returns a corresponding surface. You don't need to call the Free method +// of the returned surface, as it will be done automatically by sdl.Quit. +func SetVideoMode(w int, h int, bpp int, flags uint32) *Surface { + GlobalMutex.Lock() + var screen = C.SDL_SetVideoMode(C.int(w), C.int(h), C.int(bpp), C.Uint32(flags)) + currentVideoSurface = wrap(screen) + GlobalMutex.Unlock() + return currentVideoSurface +} + +// Returns a pointer to the current display surface. +func GetVideoSurface() *Surface { + GlobalMutex.Lock() + surface := currentVideoSurface + GlobalMutex.Unlock() + return surface +} + +// Checks to see if a particular video mode is supported. Returns 0 if not +// supported, or the bits-per-pixel of the closest available mode. +func VideoModeOK(width int, height int, bpp int, flags uint32) int { + GlobalMutex.Lock() + status := int(C.SDL_VideoModeOK(C.int(width), C.int(height), C.int(bpp), C.Uint32(flags))) + GlobalMutex.Unlock() + return status +} + +// Returns the list of available screen dimensions for the given format. +// +// NOTE: The result of this function uses a different encoding than the underlying C function. +// It returns an empty array if no modes are available, +// and nil if any dimension is okay for the given format. +func ListModes(format *PixelFormat, flags uint32) []Rect { + modes := C.SDL_ListModes((*C.SDL_PixelFormat)(cast(format)), C.Uint32(flags)) + + // No modes available + if modes == nil { + return make([]Rect, 0) + } + + // (modes == -1) --> Any dimension is ok + if uintptr(unsafe.Pointer(modes))+1 == uintptr(0) { + return nil + } + + count := 0 + ptr := *modes //first element in the list + for ptr != nil { + count++ + ptr = *(**C.SDL_Rect)(unsafe.Pointer(uintptr(unsafe.Pointer(modes)) + uintptr(count*int(unsafe.Sizeof(ptr))))) + } + + ret := make([]Rect, count) + for i := 0; i < count; i++ { + ptr := (**C.SDL_Rect)(unsafe.Pointer(uintptr(unsafe.Pointer(modes)) + uintptr(i*int(unsafe.Sizeof(*modes))))) + var r *C.SDL_Rect = *ptr + ret[i].X = int16(r.x) + ret[i].Y = int16(r.y) + ret[i].W = uint16(r.w) + ret[i].H = uint16(r.h) + } + + return ret +} + +type VideoInfo struct { + HW_available bool "Flag: Can you create hardware surfaces?" + WM_available bool "Flag: Can you talk to a window manager?" + Blit_hw bool "Flag: Accelerated blits HW --> HW" + Blit_hw_CC bool "Flag: Accelerated blits with Colorkey" + Blit_hw_A bool "Flag: Accelerated blits with Alpha" + Blit_sw bool "Flag: Accelerated blits SW --> HW" + Blit_sw_CC bool "Flag: Accelerated blits with Colorkey" + Blit_sw_A bool "Flag: Accelerated blits with Alpha" + Blit_fill bool "Flag: Accelerated color fill" + Video_mem uint32 "The total amount of video memory (in K)" + Vfmt *PixelFormat "Value: The format of the video surface" + Current_w int32 "Value: The current video mode width" + Current_h int32 "Value: The current video mode height" +} + +func GetVideoInfo() *VideoInfo { + GlobalMutex.Lock() + vinfo := (*internalVideoInfo)(cast(C.SDL_GetVideoInfo())) + GlobalMutex.Unlock() + + flags := vinfo.Flags + + return &VideoInfo{ + HW_available: flags&(1<<0) != 0, + WM_available: flags&(1<<1) != 0, + Blit_hw: flags&(1<<9) != 0, + Blit_hw_CC: flags&(1<<10) != 0, + Blit_hw_A: flags&(1<<11) != 0, + Blit_sw: flags&(1<<12) != 0, + Blit_sw_CC: flags&(1<<13) != 0, + Blit_sw_A: flags&(1<<14) != 0, + Blit_fill: flags&(1<<15) != 0, + Video_mem: vinfo.Video_mem, + Vfmt: vinfo.Vfmt, + Current_w: vinfo.Current_w, + Current_h: vinfo.Current_h, + } +} + +// Makes sure the given area is updated on the given screen. If x, y, w, and +// h are all 0, the whole screen will be updated. +func (screen *Surface) UpdateRect(x int32, y int32, w uint32, h uint32) { + GlobalMutex.Lock() + screen.mutex.Lock() + + C.SDL_UpdateRect(screen.cSurface, C.Sint32(x), C.Sint32(y), C.Uint32(w), C.Uint32(h)) + + screen.mutex.Unlock() + GlobalMutex.Unlock() +} + +func (screen *Surface) UpdateRects(rects []Rect) { + if len(rects) > 0 { + GlobalMutex.Lock() + screen.mutex.Lock() + + C.SDL_UpdateRects(screen.cSurface, C.int(len(rects)), (*C.SDL_Rect)(cast(&rects[0]))) + + screen.mutex.Unlock() + GlobalMutex.Unlock() + } +} + +// Gets the window title and icon name. +func WM_GetCaption() (title, icon string) { + GlobalMutex.Lock() + + // SDL seems to free these strings. TODO: Check to see if that's the case + var ctitle, cicon *C.char + C.SDL_WM_GetCaption(&ctitle, &cicon) + title = C.GoString(ctitle) + icon = C.GoString(cicon) + + GlobalMutex.Unlock() + + return +} + +// Sets the window title and icon name. +func WM_SetCaption(title, icon string) { + ctitle := C.CString(title) + cicon := C.CString(icon) + + GlobalMutex.Lock() + C.SDL_WM_SetCaption(ctitle, cicon) + GlobalMutex.Unlock() + + C.free(unsafe.Pointer(ctitle)) + C.free(unsafe.Pointer(cicon)) +} + +// Sets the icon for the display window. +func WM_SetIcon(icon *Surface, mask *uint8) { + GlobalMutex.Lock() + C.SDL_WM_SetIcon(icon.cSurface, (*C.Uint8)(mask)) + GlobalMutex.Unlock() +} + +// Minimizes the window +func WM_IconifyWindow() int { + GlobalMutex.Lock() + status := int(C.SDL_WM_IconifyWindow()) + GlobalMutex.Unlock() + return status +} + +// Toggles fullscreen mode +func WM_ToggleFullScreen(surface *Surface) int { + GlobalMutex.Lock() + status := int(C.SDL_WM_ToggleFullScreen(surface.cSurface)) + GlobalMutex.Unlock() + return status +} + +// Swaps OpenGL framebuffers/Update Display. +func GL_SwapBuffers() { + GlobalMutex.Lock() + C.SDL_GL_SwapBuffers() + GlobalMutex.Unlock() +} + +func GL_SetAttribute(attr int, value int) int { + GlobalMutex.Lock() + status := int(C.SDL_GL_SetAttribute(C.SDL_GLattr(attr), C.int(value))) + GlobalMutex.Unlock() + return status +} + +// Swaps screen buffers. +func (screen *Surface) Flip() int { + GlobalMutex.Lock() + screen.mutex.Lock() + + status := int(C.SDL_Flip(screen.cSurface)) + + screen.mutex.Unlock() + GlobalMutex.Unlock() + + return status +} + +// Frees (deletes) a Surface +func (screen *Surface) Free() { + GlobalMutex.Lock() + screen.mutex.Lock() + + C.SDL_FreeSurface(screen.cSurface) + + screen.destroy() + if screen == currentVideoSurface { + currentVideoSurface = nil + } + + screen.mutex.Unlock() + GlobalMutex.Unlock() +} + +// Locks a surface for direct access. +func (screen *Surface) Lock() int { + screen.mutex.Lock() + status := int(C.SDL_LockSurface(screen.cSurface)) + screen.mutex.Unlock() + return status +} + +// Unlocks a previously locked surface. +func (screen *Surface) Unlock() { + screen.mutex.Lock() + C.SDL_UnlockSurface(screen.cSurface) + screen.mutex.Unlock() +} + +// Performs a fast blit from the source surface to the destination surface. +// This is the same as func BlitSurface, but the order of arguments is reversed. +func (dst *Surface) Blit(dstrect *Rect, src *Surface, srcrect *Rect) int { + GlobalMutex.Lock() + global := true + if (src != currentVideoSurface) && (dst != currentVideoSurface) { + GlobalMutex.Unlock() + global = false + } + + // At this point: GlobalMutex is locked only if at least one of 'src' or 'dst' + // was identical to 'currentVideoSurface' + + var ret C.int + { + src.mutex.RLock() + dst.mutex.Lock() + + ret = C.SDL_UpperBlit( + src.cSurface, + (*C.SDL_Rect)(cast(srcrect)), + dst.cSurface, + (*C.SDL_Rect)(cast(dstrect))) + + dst.mutex.Unlock() + src.mutex.RUnlock() + } + + if global { + GlobalMutex.Unlock() + } + + return int(ret) +} + +// Performs a fast blit from the source surface to the destination surface. +func BlitSurface(src *Surface, srcrect *Rect, dst *Surface, dstrect *Rect) int { + return dst.Blit(dstrect, src, srcrect) +} + +// This function performs a fast fill of the given rectangle with some color. +func (dst *Surface) FillRect(dstrect *Rect, color uint32) int { + dst.mutex.Lock() + + var ret = C.SDL_FillRect( + dst.cSurface, + (*C.SDL_Rect)(cast(dstrect)), + C.Uint32(color)) + + dst.mutex.Unlock() + + return int(ret) +} + +// Adjusts the alpha properties of a Surface. +func (s *Surface) SetAlpha(flags uint32, alpha uint8) int { + s.mutex.Lock() + status := int(C.SDL_SetAlpha(s.cSurface, C.Uint32(flags), C.Uint8(alpha))) + s.mutex.Unlock() + return status +} + +// Sets the color key (transparent pixel) in a blittable surface and +// enables or disables RLE blit acceleration. +func (s *Surface) SetColorKey(flags uint32, ColorKey uint32) int { + s.mutex.Lock() + status := int(C.SDL_SetColorKey(s.cSurface, C.Uint32(flags), C.Uint32(ColorKey))) + s.mutex.Unlock() + return status +} + +// Gets the clipping rectangle for a surface. +func (s *Surface) GetClipRect(r *Rect) { + s.mutex.RLock() + C.SDL_GetClipRect(s.cSurface, (*C.SDL_Rect)(cast(r))) + s.mutex.RUnlock() +} + +// Sets the clipping rectangle for a surface. +func (s *Surface) SetClipRect(r *Rect) { + s.mutex.Lock() + C.SDL_SetClipRect(s.cSurface, (*C.SDL_Rect)(cast(r))) + s.mutex.Unlock() +} + +// Map a RGBA color value to a pixel format. +func MapRGBA(format *PixelFormat, r, g, b, a uint8) uint32 { + return (uint32)(C.SDL_MapRGBA((*C.SDL_PixelFormat)(cast(format)), (C.Uint8)(r), (C.Uint8)(g), (C.Uint8)(b), (C.Uint8)(a))) +} + +// Gets RGBA values from a pixel in the specified pixel format. +func GetRGBA(color uint32, format *PixelFormat, r, g, b, a *uint8) { + C.SDL_GetRGBA(C.Uint32(color), (*C.SDL_PixelFormat)(cast(format)), (*C.Uint8)(r), (*C.Uint8)(g), (*C.Uint8)(b), (*C.Uint8)(a)) +} + +// Loads Surface from file (using IMG_Load). +func Load(file string) *Surface { + GlobalMutex.Lock() + + cfile := C.CString(file) + var screen = C.IMG_Load(cfile) + C.free(unsafe.Pointer(cfile)) + + GlobalMutex.Unlock() + + return wrap(screen) +} + +// Creates an empty Surface. +func CreateRGBSurface(flags uint32, width int, height int, bpp int, Rmask uint32, Gmask uint32, Bmask uint32, Amask uint32) *Surface { + GlobalMutex.Lock() + + p := C.SDL_CreateRGBSurface(C.Uint32(flags), C.int(width), C.int(height), C.int(bpp), + C.Uint32(Rmask), C.Uint32(Gmask), C.Uint32(Bmask), C.Uint32(Amask)) + + GlobalMutex.Unlock() + + return wrap(p) +} + +// Creates a Surface from existing pixel data. It expects pixels to be a slice, pointer or unsafe.Pointer. +func CreateRGBSurfaceFrom(pixels interface{}, width, height, bpp, pitch int, Rmask, Gmask, Bmask, Amask uint32) *Surface { + var ptr unsafe.Pointer + switch v := reflect.ValueOf(pixels); v.Kind() { + case reflect.Ptr, reflect.UnsafePointer, reflect.Slice: + ptr = unsafe.Pointer(v.Pointer()) + default: + panic("Don't know how to handle type: " + v.Kind().String()) + } + + GlobalMutex.Lock() + p := C.SDL_CreateRGBSurfaceFrom(ptr, C.int(width), C.int(height), C.int(bpp), C.int(pitch), + C.Uint32(Rmask), C.Uint32(Gmask), C.Uint32(Bmask), C.Uint32(Amask)) + GlobalMutex.Unlock() + + s := wrap(p) + s.gcPixels = pixels + return s +} + +// Converts a surface to the display format +func (s *Surface) DisplayFormat() *Surface { + s.mutex.RLock() + p := C.SDL_DisplayFormat(s.cSurface) + s.mutex.RUnlock() + return wrap(p) +} + +// Converts a surface to the display format with alpha +func (s *Surface) DisplayFormatAlpha() *Surface { + s.mutex.RLock() + p := C.SDL_DisplayFormatAlpha(s.cSurface) + s.mutex.RUnlock() + return wrap(p) +} + +// ======== +// Keyboard +// ======== + +// Enables UNICODE translation. +func EnableUNICODE(enable int) int { + GlobalMutex.Lock() + previous := int(C.SDL_EnableUNICODE(C.int(enable))) + GlobalMutex.Unlock() + return previous +} + +// Sets keyboard repeat rate. +func EnableKeyRepeat(delay, interval int) int { + GlobalMutex.Lock() + status := int(C.SDL_EnableKeyRepeat(C.int(delay), C.int(interval))) + GlobalMutex.Unlock() + return status +} + +// Gets keyboard repeat rate. +func GetKeyRepeat() (int, int) { + var delay int + var interval int + + GlobalMutex.Lock() + C.SDL_GetKeyRepeat((*C.int)(cast(&delay)), (*C.int)(cast(&interval))) + GlobalMutex.Unlock() + + return delay, interval +} + +// Gets a snapshot of the current keyboard state +func GetKeyState() []uint8 { + GlobalMutex.Lock() + + var numkeys C.int + array := C.SDL_GetKeyState(&numkeys) + + var ptr = make([]uint8, numkeys) + + *((**C.Uint8)(unsafe.Pointer(&ptr))) = array // TODO + + GlobalMutex.Unlock() + + return ptr + +} + +// Modifier +type Mod C.int + +// Key +type Key C.int + +// Gets the state of modifier keys +func GetModState() Mod { + GlobalMutex.Lock() + state := Mod(C.SDL_GetModState()) + GlobalMutex.Unlock() + return state +} + +// Sets the state of modifier keys +func SetModState(modstate Mod) { + GlobalMutex.Lock() + C.SDL_SetModState(C.SDLMod(modstate)) + GlobalMutex.Unlock() +} + +// Gets the name of an SDL virtual keysym +func GetKeyName(key Key) string { + GlobalMutex.Lock() + name := C.GoString(C.SDL_GetKeyName(C.SDLKey(key))) + GlobalMutex.Unlock() + return name +} + +// ====== +// Events +// ====== + +// Polls for currently pending events +func (event *Event) poll() bool { + GlobalMutex.Lock() + + var ret = C.SDL_PollEvent((*C.SDL_Event)(cast(event))) + + if ret != 0 { + if (event.Type == VIDEORESIZE) && (currentVideoSurface != nil) { + currentVideoSurface.reload() + } + } + + GlobalMutex.Unlock() + + return ret != 0 +} + +// ===== +// Mouse +// ===== + +// Retrieves the current state of the mouse. +func GetMouseState(x, y *int) uint8 { + GlobalMutex.Lock() + state := uint8(C.SDL_GetMouseState((*C.int)(cast(x)), (*C.int)(cast(y)))) + GlobalMutex.Unlock() + return state +} + +// Retrieves the current state of the mouse relative to the last time this +// function was called. +func GetRelativeMouseState(x, y *int) uint8 { + GlobalMutex.Lock() + state := uint8(C.SDL_GetRelativeMouseState((*C.int)(cast(x)), (*C.int)(cast(y)))) + GlobalMutex.Unlock() + return state +} + +// Toggle whether or not the cursor is shown on the screen. +func ShowCursor(toggle int) int { + GlobalMutex.Lock() + state := int(C.SDL_ShowCursor((C.int)(toggle))) + GlobalMutex.Unlock() + return state +} + +// ======== +// Joystick +// ======== + +type Joystick struct { + cJoystick *C.SDL_Joystick +} + +func wrapJoystick(cJoystick *C.SDL_Joystick) *Joystick { + var j *Joystick + if cJoystick != nil { + var joystick Joystick + joystick.cJoystick = (*C.SDL_Joystick)(unsafe.Pointer(cJoystick)) + j = &joystick + } else { + j = nil + } + return j +} + +// Count the number of joysticks attached to the system +func NumJoysticks() int { + GlobalMutex.Lock() + num := int(C.SDL_NumJoysticks()) + GlobalMutex.Unlock() + return num +} + +// Get the implementation dependent name of a joystick. +// This can be called before any joysticks are opened. +// If no name can be found, this function returns NULL. +func JoystickName(deviceIndex int) string { + GlobalMutex.Lock() + name := C.GoString(C.SDL_JoystickName(C.int(deviceIndex))) + GlobalMutex.Unlock() + return name +} + +// Open a joystick for use The index passed as an argument refers to +// the N'th joystick on the system. This index is the value which will +// identify this joystick in future joystick events. This function +// returns a joystick identifier, or NULL if an error occurred. +func JoystickOpen(deviceIndex int) *Joystick { + GlobalMutex.Lock() + joystick := C.SDL_JoystickOpen(C.int(deviceIndex)) + GlobalMutex.Unlock() + return wrapJoystick(joystick) +} + +// Returns 1 if the joystick has been opened, or 0 if it has not. +func JoystickOpened(deviceIndex int) int { + GlobalMutex.Lock() + opened := int(C.SDL_JoystickOpened(C.int(deviceIndex))) + GlobalMutex.Unlock() + return opened +} + +// Update the current state of the open joysticks. This is called +// automatically by the event loop if any joystick events are enabled. +func JoystickUpdate() { + GlobalMutex.Lock() + C.SDL_JoystickUpdate() + GlobalMutex.Unlock() +} + +// Enable/disable joystick event polling. If joystick events are +// disabled, you must call SDL_JoystickUpdate() yourself and check the +// state of the joystick when you want joystick information. The state +// can be one of SDL_QUERY, SDL_ENABLE or SDL_IGNORE. +func JoystickEventState(state int) int { + GlobalMutex.Lock() + result := int(C.SDL_JoystickEventState(C.int(state))) + GlobalMutex.Unlock() + return result +} + +// Close a joystick previously opened with SDL_JoystickOpen() +func (joystick *Joystick) Close() { + GlobalMutex.Lock() + C.SDL_JoystickClose(joystick.cJoystick) + GlobalMutex.Unlock() +} + +// Get the number of general axis controls on a joystick +func (joystick *Joystick) NumAxes() int { + return int(C.SDL_JoystickNumAxes(joystick.cJoystick)) +} + +// Get the device index of an opened joystick. +func (joystick *Joystick) Index() int { + return int(C.SDL_JoystickIndex(joystick.cJoystick)) +} + +// Get the number of buttons on a joystick +func (joystick *Joystick) NumButtons() int { + return int(C.SDL_JoystickNumButtons(joystick.cJoystick)) +} + +// Get the number of trackballs on a Joystick trackballs have only +// relative motion events associated with them and their state cannot +// be polled. +func (joystick *Joystick) NumBalls() int { + return int(C.SDL_JoystickNumBalls(joystick.cJoystick)) +} + +// Get the number of POV hats on a joystick +func (joystick *Joystick) NumHats() int { + return int(C.SDL_JoystickNumHats(joystick.cJoystick)) +} + +// Get the current state of a POV hat on a joystick +// The hat indices start at index 0. +func (joystick *Joystick) GetHat(hat int) uint8 { + return uint8(C.SDL_JoystickGetHat(joystick.cJoystick, C.int(hat))) +} + +// Get the current state of a button on a joystick. The button indices +// start at index 0. +func (joystick *Joystick) GetButton(button int) uint8 { + return uint8(C.SDL_JoystickGetButton(joystick.cJoystick, C.int(button))) +} + +// Get the ball axis change since the last poll. The ball indices +// start at index 0. This returns 0, or -1 if you passed it invalid +// parameters. +func (joystick *Joystick) GetBall(ball int, dx, dy *int) int { + return int(C.SDL_JoystickGetBall(joystick.cJoystick, C.int(ball), (*C.int)(cast(dx)), (*C.int)(cast(dy)))) +} + +// Get the current state of an axis control on a joystick. The axis +// indices start at index 0. The state is a value ranging from -32768 +// to 32767. +func (joystick *Joystick) GetAxis(axis int) int16 { + return int16(C.SDL_JoystickGetAxis(joystick.cJoystick, C.int(axis))) +} + +// ==== +// Time +// ==== + +// Gets the number of milliseconds since the SDL library initialization. +func GetTicks() uint32 { + GlobalMutex.Lock() + t := uint32(C.SDL_GetTicks()) + GlobalMutex.Unlock() + return t +} + +// Waits a specified number of milliseconds before returning. +func Delay(ms uint32) { + time.Sleep(time.Duration(ms) * time.Millisecond) +} diff --git a/vendor/github.com/scottferg/Go-SDL/sdl/sdl_darwin.go b/vendor/github.com/scottferg/Go-SDL/sdl/sdl_darwin.go new file mode 100644 index 0000000..da434bb --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/sdl/sdl_darwin.go @@ -0,0 +1,11 @@ +package sdl + +import ( + "os" +) + +func init() { + if os.Getenv("SDL_VIDEODRIVER") == "" { + os.Setenv("SDL_VIDEODRIVER", "x11") + } +} diff --git a/vendor/github.com/scottferg/Go-SDL/sdl/structs_386.go b/vendor/github.com/scottferg/Go-SDL/sdl/structs_386.go new file mode 100644 index 0000000..647e810 --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/sdl/structs_386.go @@ -0,0 +1,171 @@ +package sdl + +type PixelFormat struct { + Palette *Palette + BitsPerPixel uint8 + BytesPerPixel uint8 + Rloss uint8 + Gloss uint8 + Bloss uint8 + Aloss uint8 + Rshift uint8 + Gshift uint8 + Bshift uint8 + Ashift uint8 + Pad0 [2]byte + Rmask uint32 + Gmask uint32 + Bmask uint32 + Amask uint32 + Colorkey uint32 + Alpha uint8 + Pad1 [3]byte +} + +type Rect struct { + X int16 + Y int16 + W uint16 + H uint16 +} + +type Color struct { + R uint8 + G uint8 + B uint8 + Unused uint8 +} + +type Palette struct { + Ncolors int32 + Colors *Color +} + +type internalVideoInfo struct { + Flags uint32 + Video_mem uint32 + Vfmt *PixelFormat + Current_w int32 + Current_h int32 +} + +type Overlay struct { + Format uint32 + W int32 + H int32 + Planes int32 + Pitches *uint16 + Pixels **uint8 + Hwfuncs *[0]byte /* sprivate_yuvhwfuncs */ + Hwdata *[0]byte /* sprivate_yuvhwdata */ + Pad0 [4]byte +} + +type ActiveEvent struct { + Type uint8 + Gain uint8 + State uint8 +} + +type KeyboardEvent struct { + Type uint8 + Which uint8 + State uint8 + Pad0 [1]byte + Keysym Keysym +} + +type MouseMotionEvent struct { + Type uint8 + Which uint8 + State uint8 + Pad0 [1]byte + X uint16 + Y uint16 + Xrel int16 + Yrel int16 +} + +type MouseButtonEvent struct { + Type uint8 + Which uint8 + Button uint8 + State uint8 + X uint16 + Y uint16 +} + +type JoyAxisEvent struct { + Type uint8 + Which uint8 + Axis uint8 + Pad0 [1]byte + Value int16 +} + +type JoyBallEvent struct { + Type uint8 + Which uint8 + Ball uint8 + Pad0 [1]byte + Xrel int16 + Yrel int16 +} + +type JoyHatEvent struct { + Type uint8 + Which uint8 + Hat uint8 + Value uint8 +} + +type JoyButtonEvent struct { + Type uint8 + Which uint8 + Button uint8 + State uint8 +} + +type ResizeEvent struct { + Type uint8 + Pad0 [3]byte + W int32 + H int32 +} + +type ExposeEvent struct { + Type uint8 +} + +type QuitEvent struct { + Type uint8 +} + +type UserEvent struct { + Type uint8 + Pad0 [3]byte + Code int32 + Data1 *byte + Data2 *byte +} + +type SysWMmsg struct{} + +type SysWMEvent struct { + Type uint8 + Pad0 [3]byte + Msg *SysWMmsg +} + +type Event struct { + Type uint8 + Pad0 [19]byte +} + +type Keysym struct { + Scancode uint8 + Pad0 [3]byte + Sym uint32 + Mod uint32 + Unicode uint16 +} diff --git a/vendor/github.com/scottferg/Go-SDL/sdl/structs_amd64.go b/vendor/github.com/scottferg/Go-SDL/sdl/structs_amd64.go new file mode 100644 index 0000000..0c7a48a --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/sdl/structs_amd64.go @@ -0,0 +1,172 @@ +package sdl + +type PixelFormat struct { + Palette *Palette + BitsPerPixel uint8 + BytesPerPixel uint8 + Rloss uint8 + Gloss uint8 + Bloss uint8 + Aloss uint8 + Rshift uint8 + Gshift uint8 + Bshift uint8 + Ashift uint8 + Pad0 [2]byte + Rmask uint32 + Gmask uint32 + Bmask uint32 + Amask uint32 + Colorkey uint32 + Alpha uint8 + Pad1 [7]byte +} + +type Rect struct { + X int16 + Y int16 + W uint16 + H uint16 +} + +type Color struct { + R uint8 + G uint8 + B uint8 + Unused uint8 +} + +type Palette struct { + Ncolors int32 + Pad0 [4]byte + Colors *Color +} + +type internalVideoInfo struct { + Flags uint32 + Video_mem uint32 + Vfmt *PixelFormat + Current_w int32 + Current_h int32 +} + +type Overlay struct { + Format uint32 + W int32 + H int32 + Planes int32 + Pitches *uint16 + Pixels **uint8 + Hwfuncs *[0]byte /* sprivate_yuvhwfuncs */ + Hwdata *[0]byte /* sprivate_yuvhwdata */ + Pad0 [8]byte +} + +type ActiveEvent struct { + Type uint8 + Gain uint8 + State uint8 +} + +type KeyboardEvent struct { + Type uint8 + Which uint8 + State uint8 + Pad0 [1]byte + Keysym Keysym +} + +type MouseMotionEvent struct { + Type uint8 + Which uint8 + State uint8 + Pad0 [1]byte + X uint16 + Y uint16 + Xrel int16 + Yrel int16 +} + +type MouseButtonEvent struct { + Type uint8 + Which uint8 + Button uint8 + State uint8 + X uint16 + Y uint16 +} + +type JoyAxisEvent struct { + Type uint8 + Which uint8 + Axis uint8 + Pad0 [1]byte + Value int16 +} + +type JoyBallEvent struct { + Type uint8 + Which uint8 + Ball uint8 + Pad0 [1]byte + Xrel int16 + Yrel int16 +} + +type JoyHatEvent struct { + Type uint8 + Which uint8 + Hat uint8 + Value uint8 +} + +type JoyButtonEvent struct { + Type uint8 + Which uint8 + Button uint8 + State uint8 +} + +type ResizeEvent struct { + Type uint8 + Pad0 [3]byte + W int32 + H int32 +} + +type ExposeEvent struct { + Type uint8 +} + +type QuitEvent struct { + Type uint8 +} + +type UserEvent struct { + Type uint8 + Pad0 [3]byte + Code int32 + Data1 *byte + Data2 *byte +} + +type SysWMmsg struct{} + +type SysWMEvent struct { + Type uint8 + Pad0 [7]byte + Msg *SysWMmsg +} + +type Event struct { + Type uint8 + Pad0 [23]byte +} + +type Keysym struct { + Scancode uint8 + Pad0 [3]byte + Sym uint32 + Mod uint32 + Unicode uint16 +} diff --git a/vendor/github.com/scottferg/Go-SDL/sdl/structs_arm.go b/vendor/github.com/scottferg/Go-SDL/sdl/structs_arm.go new file mode 100644 index 0000000..647e810 --- /dev/null +++ b/vendor/github.com/scottferg/Go-SDL/sdl/structs_arm.go @@ -0,0 +1,171 @@ +package sdl + +type PixelFormat struct { + Palette *Palette + BitsPerPixel uint8 + BytesPerPixel uint8 + Rloss uint8 + Gloss uint8 + Bloss uint8 + Aloss uint8 + Rshift uint8 + Gshift uint8 + Bshift uint8 + Ashift uint8 + Pad0 [2]byte + Rmask uint32 + Gmask uint32 + Bmask uint32 + Amask uint32 + Colorkey uint32 + Alpha uint8 + Pad1 [3]byte +} + +type Rect struct { + X int16 + Y int16 + W uint16 + H uint16 +} + +type Color struct { + R uint8 + G uint8 + B uint8 + Unused uint8 +} + +type Palette struct { + Ncolors int32 + Colors *Color +} + +type internalVideoInfo struct { + Flags uint32 + Video_mem uint32 + Vfmt *PixelFormat + Current_w int32 + Current_h int32 +} + +type Overlay struct { + Format uint32 + W int32 + H int32 + Planes int32 + Pitches *uint16 + Pixels **uint8 + Hwfuncs *[0]byte /* sprivate_yuvhwfuncs */ + Hwdata *[0]byte /* sprivate_yuvhwdata */ + Pad0 [4]byte +} + +type ActiveEvent struct { + Type uint8 + Gain uint8 + State uint8 +} + +type KeyboardEvent struct { + Type uint8 + Which uint8 + State uint8 + Pad0 [1]byte + Keysym Keysym +} + +type MouseMotionEvent struct { + Type uint8 + Which uint8 + State uint8 + Pad0 [1]byte + X uint16 + Y uint16 + Xrel int16 + Yrel int16 +} + +type MouseButtonEvent struct { + Type uint8 + Which uint8 + Button uint8 + State uint8 + X uint16 + Y uint16 +} + +type JoyAxisEvent struct { + Type uint8 + Which uint8 + Axis uint8 + Pad0 [1]byte + Value int16 +} + +type JoyBallEvent struct { + Type uint8 + Which uint8 + Ball uint8 + Pad0 [1]byte + Xrel int16 + Yrel int16 +} + +type JoyHatEvent struct { + Type uint8 + Which uint8 + Hat uint8 + Value uint8 +} + +type JoyButtonEvent struct { + Type uint8 + Which uint8 + Button uint8 + State uint8 +} + +type ResizeEvent struct { + Type uint8 + Pad0 [3]byte + W int32 + H int32 +} + +type ExposeEvent struct { + Type uint8 +} + +type QuitEvent struct { + Type uint8 +} + +type UserEvent struct { + Type uint8 + Pad0 [3]byte + Code int32 + Data1 *byte + Data2 *byte +} + +type SysWMmsg struct{} + +type SysWMEvent struct { + Type uint8 + Pad0 [3]byte + Msg *SysWMmsg +} + +type Event struct { + Type uint8 + Pad0 [19]byte +} + +type Keysym struct { + Scancode uint8 + Pad0 [3]byte + Sym uint32 + Mod uint32 + Unicode uint16 +} diff --git a/vendor/vendor.json b/vendor/vendor.json new file mode 100644 index 0000000..01e3602 --- /dev/null +++ b/vendor/vendor.json @@ -0,0 +1,61 @@ +{ + "comment": "", + "ignore": "test", + "package": [ + { + "path": "github.com/go-gl-legacy/gl", + "revision": "df25b1fe668dbfe300dda6ebca5f3c7397e8ce02", + "revisionTime": "2015-02-22T20:33:40-07:00" + }, + { + "path": "github.com/robertkrimen/otto", + "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", + "revisionTime": "2014-07-02T21:32:54-07:00" + }, + { + "path": "github.com/robertkrimen/otto/ast", + "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", + "revisionTime": "2014-07-02T21:32:54-07:00" + }, + { + "path": "github.com/robertkrimen/otto/dbg", + "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", + "revisionTime": "2014-07-02T21:32:54-07:00" + }, + { + "path": "github.com/robertkrimen/otto/file", + "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", + "revisionTime": "2014-07-02T21:32:54-07:00" + }, + { + "path": "github.com/robertkrimen/otto/parser", + "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", + "revisionTime": "2014-07-02T21:32:54-07:00" + }, + { + "path": "github.com/robertkrimen/otto/registry", + "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", + "revisionTime": "2014-07-02T21:32:54-07:00" + }, + { + "path": "github.com/robertkrimen/otto/token", + "revision": "dea31a3d392779af358ec41f77a07fcc7e9d04ba", + "revisionTime": "2014-07-02T21:32:54-07:00" + }, + { + "path": "github.com/scottferg/Go-SDL/gfx", + "revision": "0d190b34634e10542215b00d6fe69f2b7f1254ce", + "revisionTime": "2013-09-19T12:59:28-07:00" + }, + { + "path": "github.com/scottferg/Go-SDL/sdl", + "revision": "0d190b34634e10542215b00d6fe69f2b7f1254ce", + "revisionTime": "2013-09-19T12:59:28-07:00" + }, + { + "path": "github.com/scottferg/Go-SDL/sdl/audio", + "revision": "0d190b34634e10542215b00d6fe69f2b7f1254ce", + "revisionTime": "2013-09-19T12:59:28-07:00" + } + ] +} diff --git a/video.go b/video.go index 0c4e793..56f13d7 100644 --- a/video.go +++ b/video.go @@ -2,14 +2,15 @@ package main import ( "fmt" - "github.com/go-gl/gl" - "github.com/scottferg/Fergulator/nes" - "github.com/scottferg/Go-SDL/gfx" - "github.com/scottferg/Go-SDL/sdl" "log" "math" "os" "unsafe" + + "github.com/go-gl-legacy/gl" + "github.com/scottferg/Fergulator/nes" + "github.com/scottferg/Go-SDL/gfx" + "github.com/scottferg/Go-SDL/sdl" ) type Video struct {